diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..4f7c5040 --- /dev/null +++ b/404.html @@ -0,0 +1,31 @@ + + + + + + + + + ScyllaDB + + + + + + + + + + + +
+

404

+

The ScyllaDB monster ate your page!

+

+ Home +

+
+ + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..35a90dad --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +iot.scylladb.com \ No newline at end of file diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..30fee9d0 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/check-solid.svg b/_static/check-solid.svg new file mode 100644 index 00000000..92fad4b5 --- /dev/null +++ b/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/clipboard.min.js b/_static/clipboard.min.js new file mode 100644 index 00000000..54b3c463 --- /dev/null +++ b/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/_static/copybutton.css b/_static/copybutton.css new file mode 100644 index 00000000..f1916ec7 --- /dev/null +++ b/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/_static/copybutton.js b/_static/copybutton.js new file mode 100644 index 00000000..2ea7ff3e --- /dev/null +++ b/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js new file mode 100644 index 00000000..dbe1aaad --- /dev/null +++ b/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/_static/css/main.css b/_static/css/main.css new file mode 100644 index 00000000..65eb0a55 --- /dev/null +++ b/_static/css/main.css @@ -0,0 +1 @@ +@media print,screen and (min-width:40em){.reveal,.reveal.large,.reveal.small,.reveal.tiny{left:auto;margin:0 auto;right:auto}}/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */html{-webkit-text-size-adjust:100%;line-height:1.15}h1{font-size:2em;margin:.67em 0}hr{-webkit-box-sizing:content-box;box-sizing:content-box;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:0;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}[data-whatinput=mouse] *,[data-whatinput=mouse] :focus,[data-whatinput=touch] *,[data-whatinput=touch] :focus,[data-whatintent=mouse] *,[data-whatintent=mouse] :focus,[data-whatintent=touch] *,[data-whatintent=touch] :focus{outline:0}[draggable=false]{-webkit-touch-callout:none;-webkit-user-select:none}.foundation-mq{font-family:"small=0em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"}html{-webkit-box-sizing:border-box;font-size:100%}*,:after,:before{-webkit-box-sizing:inherit}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:#fefefe;color:#0a0a0a;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:1.5;margin:0;padding:0}img{-ms-interpolation-mode:bicubic;display:inline-block;height:auto;vertical-align:middle}textarea{border-radius:0;height:auto;min-height:50px}select{-webkit-box-sizing:border-box;box-sizing:border-box;width:100%}.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:0 0;border:0;border-radius:0;cursor:auto;line-height:1;padding:0}[data-whatinput=mouse] button{outline:0}pre{-webkit-overflow-scrolling:touch;overflow:auto}button,input,optgroup,select,textarea{font-family:inherit}.is-visible{display:block!important}.is-hidden{display:none!important}[type=color],[type=date],[type=datetime-local],[type=datetime],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fefefe;border:1px solid #cacaca;border-radius:0;-webkit-box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);-webkit-box-sizing:border-box;box-sizing:border-box;color:#0a0a0a;display:block;font-family:inherit;font-size:1rem;font-weight:400;height:2.4375rem;line-height:1.5;margin:0 0 1rem;padding:.5rem;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s;width:100%}[type=color]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=datetime]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,textarea:focus{background-color:#fefefe;border:1px solid #8a8a8a;-webkit-box-shadow:0 0 5px #cacaca;box-shadow:0 0 5px #cacaca;outline:0;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}textarea{max-width:100%}textarea[rows]{height:auto}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#e6e6e6;cursor:not-allowed}[type=button],[type=submit]{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}input[type=search]{-webkit-box-sizing:border-box;box-sizing:border-box}::-webkit-input-placeholder{color:#cacaca}::-moz-placeholder{color:#cacaca}:-ms-input-placeholder{color:#cacaca}::-ms-input-placeholder{color:#cacaca}::placeholder{color:#cacaca}[type=checkbox],[type=file],[type=radio]{margin:0 0 1rem}[type=checkbox]+label,[type=radio]+label{display:inline-block;margin-bottom:0;margin-left:.5rem;margin-right:1rem;vertical-align:baseline}[type=checkbox]+label[for],[type=radio]+label[for]{cursor:pointer}label>[type=checkbox],label>[type=radio]{margin-right:.5rem}[type=file]{width:100%}label{color:#0a0a0a;display:block;font-size:.875rem;font-weight:400;line-height:1.8;margin:0}label.middle{line-height:1.5;margin:0 0 1rem;padding:.5625rem 0}.help-text{color:#0a0a0a;font-size:.8125rem;font-style:italic;margin-top:-.5rem}.input-group{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-bottom:1rem;width:100%}.input-group>:first-child,.input-group>:first-child.input-group-button>*,.input-group>:last-child,.input-group>:last-child.input-group-button>*{border-radius:0}.input-group-button,.input-group-button a,.input-group-button button,.input-group-button input,.input-group-button label,.input-group-field,.input-group-label{margin:0;white-space:nowrap}.input-group-label{-webkit-box-flex:0;-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;background:#e6e6e6;border:1px solid #cacaca;color:#0a0a0a;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;padding:0 1rem;text-align:center;white-space:nowrap}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.input-group-field{-webkit-box-flex:1;border-radius:0;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px;min-width:0}.input-group-button{-webkit-box-flex:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;padding-bottom:0;padding-top:0;text-align:center}.input-group-button a,.input-group-button button,.input-group-button input,.input-group-button label{-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;font-size:1rem;height:auto;padding-bottom:0;padding-top:0}fieldset{border:0;margin:0;padding:0}legend{margin-bottom:.5rem;max-width:100%}.fieldset{border:1px solid #cacaca;margin:1.125rem 0;padding:1.25rem}.fieldset legend{margin:0 0 0 -.1875rem;padding:0 .1875rem}select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fefefe;background-image:url('data:image/svg+xml;utf8,');background-origin:content-box;background-position:right -1rem center;background-repeat:no-repeat;background-size:9px 6px;border:1px solid #cacaca;border-radius:0;color:#0a0a0a;font-family:inherit;font-size:1rem;font-weight:400;height:2.4375rem;line-height:1.5;margin:0 0 1rem;padding:.5rem 1.5rem .5rem .5rem;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}@media screen and (min-width:0\0){select{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==)}}select:focus{background-color:#fefefe;border:1px solid #8a8a8a;-webkit-box-shadow:0 0 5px #cacaca;box-shadow:0 0 5px #cacaca;outline:0;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}select:disabled{background-color:#e6e6e6;cursor:not-allowed}select::-ms-expand{display:none}select[multiple]{background-image:none;height:auto}select:not([multiple]){padding-bottom:0;padding-top:0}.is-invalid-input:not(:focus){background-color:#f9ecea;border-color:#cc4b37}.is-invalid-input:not(:focus)::-webkit-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus)::-moz-placeholder{color:#cc4b37}.is-invalid-input:not(:focus):-ms-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus)::-ms-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus)::placeholder{color:#cc4b37}.form-error,.is-invalid-label{color:#cc4b37}.form-error{display:none;font-size:.75rem;font-weight:700;margin-bottom:1rem;margin-top:-.5rem}.form-error.is-visible{display:block}blockquote,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,li,ol,p,pre,td,th,ul{margin:0;padding:0}p{font-size:inherit;line-height:1.6;margin-bottom:1rem;text-rendering:optimizeLegibility}em,i{font-style:italic}b,em,i,strong{line-height:inherit}b,strong{font-weight:700}small{font-size:80%;line-height:inherit}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{color:inherit;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-style:normal;font-weight:400;text-rendering:optimizeLegibility}.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#cacaca;line-height:0}.h1,h1{font-size:1.5rem}.h1,.h2,h1,h2{line-height:1.4;margin-bottom:.5rem;margin-top:0}.h2,h2{font-size:1.25rem}.h3,h3{font-size:1.1875rem}.h3,.h4,h3,h4{line-height:1.4;margin-bottom:.5rem;margin-top:0}.h4,h4{font-size:1.125rem}.h5,h5{font-size:1.0625rem}.h5,.h6,h5,h6{line-height:1.4;margin-bottom:.5rem;margin-top:0}.h6,h6{font-size:1rem}@media print,screen and (min-width:40em){.h1,h1{font-size:3rem}.h2,h2{font-size:2.5rem}.h3,h3{font-size:1.9375rem}.h4,h4{font-size:1.5625rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}}a{color:#1779ba;cursor:pointer;line-height:inherit;text-decoration:none}a:focus,a:hover{color:#1468a0}a img,hr{border:0}hr{border-bottom:1px solid #cacaca;clear:both;height:0;margin:1.25rem auto;max-width:75rem}dl,ol,ul{line-height:1.6;list-style-position:outside;margin-bottom:1rem}li{font-size:inherit}ul{list-style-type:disc}ol,ul{margin-left:1.25rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0;margin-left:1.25rem}dl{margin-bottom:1rem}dl dt{font-weight:700;margin-bottom:.3rem}blockquote{border-left:1px solid #cacaca;margin:0 0 1rem;padding:.5625rem 1.25rem 0 1.1875rem}blockquote,blockquote p{color:#8a8a8a;line-height:1.6}abbr,abbr[title]{border-bottom:1px dotted #0a0a0a;cursor:help;text-decoration:none}figure,kbd{margin:0}kbd{background-color:#e6e6e6;color:#0a0a0a;font-family:Consolas,Liberation Mono,Courier,monospace;padding:.125rem .25rem 0}.subheader{color:#8a8a8a;font-weight:400;line-height:1.4;margin-bottom:.5rem;margin-top:.2rem}.lead{font-size:125%;line-height:1.6}.stat{font-size:2.5rem;line-height:1}p+.stat{margin-top:-1rem}ol.no-bullet,ul.no-bullet{list-style:none;margin-left:0}.cite-block,cite{color:#8a8a8a;display:block;font-size:.8125rem}.cite-block:before,cite:before{content:"— "}.code-inline,code{word-wrap:break-word;display:inline;max-width:100%;padding:.125rem .3125rem .0625rem}.code-block,.code-inline,code{background-color:#e6e6e6;border:1px solid #cacaca;color:#0a0a0a;font-family:Consolas,Liberation Mono,Courier,monospace;font-weight:400}.code-block{display:block;margin-bottom:1.5rem;overflow:auto;padding:1rem;white-space:pre}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}@media print,screen and (min-width:40em){.medium-text-left{text-align:left}.medium-text-right{text-align:right}.medium-text-center{text-align:center}.medium-text-justify{text-align:justify}}@media print,screen and (min-width:64em){.large-text-left{text-align:left}.large-text-right{text-align:right}.large-text-center{text-align:center}.large-text-justify{text-align:justify}}.show-for-print{display:none!important}@media print{*{background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important;color:#000!important;-webkit-print-color-adjust:economy;print-color-adjust:economy;text-shadow:none!important}.show-for-print{display:block!important}.hide-for-print{display:none!important}table.show-for-print{display:table!important}thead.show-for-print{display:table-header-group!important}tbody.show-for-print{display:table-row-group!important}tr.show-for-print{display:table-row!important}td.show-for-print,th.show-for-print{display:table-cell!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}abbr[title]:after{content:" (" attr(title) ")"}blockquote,pre{border:1px solid #8a8a8a;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.print-break-inside{page-break-inside:auto}}.grid-container{margin-left:auto;margin-right:auto;max-width:75rem;padding-left:.625rem;padding-right:.625rem}@media print,screen and (min-width:40em){.grid-container{padding-left:.9375rem;padding-right:.9375rem}}.grid-container.fluid{margin-left:auto;margin-right:auto;max-width:100%;padding-left:.625rem;padding-right:.625rem}@media print,screen and (min-width:40em){.grid-container.fluid{padding-left:.9375rem;padding-right:.9375rem}}.grid-container.full{margin-left:auto;margin-right:auto;max-width:100%;padding-left:0;padding-right:0}.grid-x{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap}.cell{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;min-height:0;min-width:0;width:100%}.cell.auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0}.cell.shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-x>.auto,.grid-x>.shrink{width:auto}.grid-x>.small-1,.grid-x>.small-10,.grid-x>.small-11,.grid-x>.small-12,.grid-x>.small-2,.grid-x>.small-3,.grid-x>.small-4,.grid-x>.small-5,.grid-x>.small-6,.grid-x>.small-7,.grid-x>.small-8,.grid-x>.small-9,.grid-x>.small-full,.grid-x>.small-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}@media print,screen and (min-width:40em){.grid-x>.medium-1,.grid-x>.medium-10,.grid-x>.medium-11,.grid-x>.medium-12,.grid-x>.medium-2,.grid-x>.medium-3,.grid-x>.medium-4,.grid-x>.medium-5,.grid-x>.medium-6,.grid-x>.medium-7,.grid-x>.medium-8,.grid-x>.medium-9,.grid-x>.medium-full,.grid-x>.medium-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}}@media print,screen and (min-width:64em){.grid-x>.large-1,.grid-x>.large-10,.grid-x>.large-11,.grid-x>.large-12,.grid-x>.large-2,.grid-x>.large-3,.grid-x>.large-4,.grid-x>.large-5,.grid-x>.large-6,.grid-x>.large-7,.grid-x>.large-8,.grid-x>.large-9,.grid-x>.large-full,.grid-x>.large-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}}.grid-x>.small-1,.grid-x>.small-10,.grid-x>.small-11,.grid-x>.small-12,.grid-x>.small-2,.grid-x>.small-3,.grid-x>.small-4,.grid-x>.small-5,.grid-x>.small-6,.grid-x>.small-7,.grid-x>.small-8,.grid-x>.small-9{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-x>.small-1{width:8.3333333333%}.grid-x>.small-2{width:16.6666666667%}.grid-x>.small-3{width:25%}.grid-x>.small-4{width:33.3333333333%}.grid-x>.small-5{width:41.6666666667%}.grid-x>.small-6{width:50%}.grid-x>.small-7{width:58.3333333333%}.grid-x>.small-8{width:66.6666666667%}.grid-x>.small-9{width:75%}.grid-x>.small-10{width:83.3333333333%}.grid-x>.small-11{width:91.6666666667%}.grid-x>.small-12{width:100%}@media print,screen and (min-width:40em){.grid-x>.medium-auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;width:auto}.grid-x>.medium-1,.grid-x>.medium-10,.grid-x>.medium-11,.grid-x>.medium-12,.grid-x>.medium-2,.grid-x>.medium-3,.grid-x>.medium-4,.grid-x>.medium-5,.grid-x>.medium-6,.grid-x>.medium-7,.grid-x>.medium-8,.grid-x>.medium-9,.grid-x>.medium-shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-x>.medium-shrink{width:auto}.grid-x>.medium-1{width:8.3333333333%}.grid-x>.medium-2{width:16.6666666667%}.grid-x>.medium-3{width:25%}.grid-x>.medium-4{width:33.3333333333%}.grid-x>.medium-5{width:41.6666666667%}.grid-x>.medium-6{width:50%}.grid-x>.medium-7{width:58.3333333333%}.grid-x>.medium-8{width:66.6666666667%}.grid-x>.medium-9{width:75%}.grid-x>.medium-10{width:83.3333333333%}.grid-x>.medium-11{width:91.6666666667%}.grid-x>.medium-12{width:100%}}@media print,screen and (min-width:64em){.grid-x>.large-auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;width:auto}.grid-x>.large-1,.grid-x>.large-10,.grid-x>.large-11,.grid-x>.large-12,.grid-x>.large-2,.grid-x>.large-3,.grid-x>.large-4,.grid-x>.large-5,.grid-x>.large-6,.grid-x>.large-7,.grid-x>.large-8,.grid-x>.large-9,.grid-x>.large-shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-x>.large-shrink{width:auto}.grid-x>.large-1{width:8.3333333333%}.grid-x>.large-2{width:16.6666666667%}.grid-x>.large-3{width:25%}.grid-x>.large-4{width:33.3333333333%}.grid-x>.large-5{width:41.6666666667%}.grid-x>.large-6{width:50%}.grid-x>.large-7{width:58.3333333333%}.grid-x>.large-8{width:66.6666666667%}.grid-x>.large-9{width:75%}.grid-x>.large-10{width:83.3333333333%}.grid-x>.large-11{width:91.6666666667%}.grid-x>.large-12{width:100%}}.grid-margin-x:not(.grid-x)>.cell{width:auto}.grid-margin-y:not(.grid-y)>.cell{height:auto}.grid-margin-x{margin-left:-.625rem;margin-right:-.625rem}@media print,screen and (min-width:40em){.grid-margin-x{margin-left:-.9375rem;margin-right:-.9375rem}}.grid-margin-x>.cell{margin-left:.625rem;margin-right:.625rem;width:calc(100% - 1.25rem)}@media print,screen and (min-width:40em){.grid-margin-x>.cell{margin-left:.9375rem;margin-right:.9375rem;width:calc(100% - 1.875rem)}}.grid-margin-x>.auto,.grid-margin-x>.shrink{width:auto}.grid-margin-x>.small-1{width:calc(8.33333% - 1.25rem)}.grid-margin-x>.small-2{width:calc(16.66667% - 1.25rem)}.grid-margin-x>.small-3{width:calc(25% - 1.25rem)}.grid-margin-x>.small-4{width:calc(33.33333% - 1.25rem)}.grid-margin-x>.small-5{width:calc(41.66667% - 1.25rem)}.grid-margin-x>.small-6{width:calc(50% - 1.25rem)}.grid-margin-x>.small-7{width:calc(58.33333% - 1.25rem)}.grid-margin-x>.small-8{width:calc(66.66667% - 1.25rem)}.grid-margin-x>.small-9{width:calc(75% - 1.25rem)}.grid-margin-x>.small-10{width:calc(83.33333% - 1.25rem)}.grid-margin-x>.small-11{width:calc(91.66667% - 1.25rem)}.grid-margin-x>.small-12{width:calc(100% - 1.25rem)}@media print,screen and (min-width:40em){.grid-margin-x>.auto,.grid-margin-x>.shrink{width:auto}.grid-margin-x>.small-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.small-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.small-3{width:calc(25% - 1.875rem)}.grid-margin-x>.small-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.small-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.small-6{width:calc(50% - 1.875rem)}.grid-margin-x>.small-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.small-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.small-9{width:calc(75% - 1.875rem)}.grid-margin-x>.small-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.small-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.small-12{width:calc(100% - 1.875rem)}.grid-margin-x>.medium-auto,.grid-margin-x>.medium-shrink{width:auto}.grid-margin-x>.medium-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.medium-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.medium-3{width:calc(25% - 1.875rem)}.grid-margin-x>.medium-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.medium-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.medium-6{width:calc(50% - 1.875rem)}.grid-margin-x>.medium-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.medium-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.medium-9{width:calc(75% - 1.875rem)}.grid-margin-x>.medium-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.medium-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.medium-12{width:calc(100% - 1.875rem)}}@media print,screen and (min-width:64em){.grid-margin-x>.large-auto,.grid-margin-x>.large-shrink{width:auto}.grid-margin-x>.large-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.large-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.large-3{width:calc(25% - 1.875rem)}.grid-margin-x>.large-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.large-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.large-6{width:calc(50% - 1.875rem)}.grid-margin-x>.large-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.large-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.large-9{width:calc(75% - 1.875rem)}.grid-margin-x>.large-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.large-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.large-12{width:calc(100% - 1.875rem)}}.grid-padding-x .grid-padding-x{margin-left:-.625rem;margin-right:-.625rem}@media print,screen and (min-width:40em){.grid-padding-x .grid-padding-x{margin-left:-.9375rem;margin-right:-.9375rem}}.grid-container:not(.full)>.grid-padding-x{margin-left:-.625rem;margin-right:-.625rem}@media print,screen and (min-width:40em){.grid-container:not(.full)>.grid-padding-x{margin-left:-.9375rem;margin-right:-.9375rem}}.grid-padding-x>.cell{padding-left:.625rem;padding-right:.625rem}@media print,screen and (min-width:40em){.grid-padding-x>.cell{padding-left:.9375rem;padding-right:.9375rem}}.small-up-1>.cell{width:100%}.small-up-2>.cell{width:50%}.small-up-3>.cell{width:33.3333333333%}.small-up-4>.cell{width:25%}.small-up-5>.cell{width:20%}.small-up-6>.cell{width:16.6666666667%}.small-up-7>.cell{width:14.2857142857%}.small-up-8>.cell{width:12.5%}@media print,screen and (min-width:40em){.medium-up-1>.cell{width:100%}.medium-up-2>.cell{width:50%}.medium-up-3>.cell{width:33.3333333333%}.medium-up-4>.cell{width:25%}.medium-up-5>.cell{width:20%}.medium-up-6>.cell{width:16.6666666667%}.medium-up-7>.cell{width:14.2857142857%}.medium-up-8>.cell{width:12.5%}}@media print,screen and (min-width:64em){.large-up-1>.cell{width:100%}.large-up-2>.cell{width:50%}.large-up-3>.cell{width:33.3333333333%}.large-up-4>.cell{width:25%}.large-up-5>.cell{width:20%}.large-up-6>.cell{width:16.6666666667%}.large-up-7>.cell{width:14.2857142857%}.large-up-8>.cell{width:12.5%}}.grid-margin-x.small-up-1>.cell{width:calc(100% - 1.25rem)}.grid-margin-x.small-up-2>.cell{width:calc(50% - 1.25rem)}.grid-margin-x.small-up-3>.cell{width:calc(33.33333% - 1.25rem)}.grid-margin-x.small-up-4>.cell{width:calc(25% - 1.25rem)}.grid-margin-x.small-up-5>.cell{width:calc(20% - 1.25rem)}.grid-margin-x.small-up-6>.cell{width:calc(16.66667% - 1.25rem)}.grid-margin-x.small-up-7>.cell{width:calc(14.28571% - 1.25rem)}.grid-margin-x.small-up-8>.cell{width:calc(12.5% - 1.25rem)}@media print,screen and (min-width:40em){.grid-margin-x.small-up-1>.cell{width:calc(100% - 1.875rem)}.grid-margin-x.small-up-2>.cell{width:calc(50% - 1.875rem)}.grid-margin-x.small-up-3>.cell{width:calc(33.33333% - 1.875rem)}.grid-margin-x.small-up-4>.cell{width:calc(25% - 1.875rem)}.grid-margin-x.small-up-5>.cell{width:calc(20% - 1.875rem)}.grid-margin-x.small-up-6>.cell{width:calc(16.66667% - 1.875rem)}.grid-margin-x.small-up-7>.cell{width:calc(14.28571% - 1.875rem)}.grid-margin-x.small-up-8>.cell{width:calc(12.5% - 1.875rem)}.grid-margin-x.medium-up-1>.cell{width:calc(100% - 1.875rem)}.grid-margin-x.medium-up-2>.cell{width:calc(50% - 1.875rem)}.grid-margin-x.medium-up-3>.cell{width:calc(33.33333% - 1.875rem)}.grid-margin-x.medium-up-4>.cell{width:calc(25% - 1.875rem)}.grid-margin-x.medium-up-5>.cell{width:calc(20% - 1.875rem)}.grid-margin-x.medium-up-6>.cell{width:calc(16.66667% - 1.875rem)}.grid-margin-x.medium-up-7>.cell{width:calc(14.28571% - 1.875rem)}.grid-margin-x.medium-up-8>.cell{width:calc(12.5% - 1.875rem)}}@media print,screen and (min-width:64em){.grid-margin-x.large-up-1>.cell{width:calc(100% - 1.875rem)}.grid-margin-x.large-up-2>.cell{width:calc(50% - 1.875rem)}.grid-margin-x.large-up-3>.cell{width:calc(33.33333% - 1.875rem)}.grid-margin-x.large-up-4>.cell{width:calc(25% - 1.875rem)}.grid-margin-x.large-up-5>.cell{width:calc(20% - 1.875rem)}.grid-margin-x.large-up-6>.cell{width:calc(16.66667% - 1.875rem)}.grid-margin-x.large-up-7>.cell{width:calc(14.28571% - 1.875rem)}.grid-margin-x.large-up-8>.cell{width:calc(12.5% - 1.875rem)}}.small-margin-collapse,.small-margin-collapse>.cell{margin-left:0;margin-right:0}.small-margin-collapse>.small-1{width:8.3333333333%}.small-margin-collapse>.small-2{width:16.6666666667%}.small-margin-collapse>.small-3{width:25%}.small-margin-collapse>.small-4{width:33.3333333333%}.small-margin-collapse>.small-5{width:41.6666666667%}.small-margin-collapse>.small-6{width:50%}.small-margin-collapse>.small-7{width:58.3333333333%}.small-margin-collapse>.small-8{width:66.6666666667%}.small-margin-collapse>.small-9{width:75%}.small-margin-collapse>.small-10{width:83.3333333333%}.small-margin-collapse>.small-11{width:91.6666666667%}.small-margin-collapse>.small-12{width:100%}@media print,screen and (min-width:40em){.small-margin-collapse>.medium-1{width:8.3333333333%}.small-margin-collapse>.medium-2{width:16.6666666667%}.small-margin-collapse>.medium-3{width:25%}.small-margin-collapse>.medium-4{width:33.3333333333%}.small-margin-collapse>.medium-5{width:41.6666666667%}.small-margin-collapse>.medium-6{width:50%}.small-margin-collapse>.medium-7{width:58.3333333333%}.small-margin-collapse>.medium-8{width:66.6666666667%}.small-margin-collapse>.medium-9{width:75%}.small-margin-collapse>.medium-10{width:83.3333333333%}.small-margin-collapse>.medium-11{width:91.6666666667%}.small-margin-collapse>.medium-12{width:100%}}@media print,screen and (min-width:64em){.small-margin-collapse>.large-1{width:8.3333333333%}.small-margin-collapse>.large-2{width:16.6666666667%}.small-margin-collapse>.large-3{width:25%}.small-margin-collapse>.large-4{width:33.3333333333%}.small-margin-collapse>.large-5{width:41.6666666667%}.small-margin-collapse>.large-6{width:50%}.small-margin-collapse>.large-7{width:58.3333333333%}.small-margin-collapse>.large-8{width:66.6666666667%}.small-margin-collapse>.large-9{width:75%}.small-margin-collapse>.large-10{width:83.3333333333%}.small-margin-collapse>.large-11{width:91.6666666667%}.small-margin-collapse>.large-12{width:100%}}.small-padding-collapse{margin-left:0;margin-right:0}.small-padding-collapse>.cell{padding-left:0;padding-right:0}@media print,screen and (min-width:40em){.medium-margin-collapse,.medium-margin-collapse>.cell{margin-left:0;margin-right:0}.medium-margin-collapse>.small-1{width:8.3333333333%}.medium-margin-collapse>.small-2{width:16.6666666667%}.medium-margin-collapse>.small-3{width:25%}.medium-margin-collapse>.small-4{width:33.3333333333%}.medium-margin-collapse>.small-5{width:41.6666666667%}.medium-margin-collapse>.small-6{width:50%}.medium-margin-collapse>.small-7{width:58.3333333333%}.medium-margin-collapse>.small-8{width:66.6666666667%}.medium-margin-collapse>.small-9{width:75%}.medium-margin-collapse>.small-10{width:83.3333333333%}.medium-margin-collapse>.small-11{width:91.6666666667%}.medium-margin-collapse>.small-12{width:100%}.medium-margin-collapse>.medium-1{width:8.3333333333%}.medium-margin-collapse>.medium-2{width:16.6666666667%}.medium-margin-collapse>.medium-3{width:25%}.medium-margin-collapse>.medium-4{width:33.3333333333%}.medium-margin-collapse>.medium-5{width:41.6666666667%}.medium-margin-collapse>.medium-6{width:50%}.medium-margin-collapse>.medium-7{width:58.3333333333%}.medium-margin-collapse>.medium-8{width:66.6666666667%}.medium-margin-collapse>.medium-9{width:75%}.medium-margin-collapse>.medium-10{width:83.3333333333%}.medium-margin-collapse>.medium-11{width:91.6666666667%}.medium-margin-collapse>.medium-12{width:100%}}@media print,screen and (min-width:64em){.medium-margin-collapse>.large-1{width:8.3333333333%}.medium-margin-collapse>.large-2{width:16.6666666667%}.medium-margin-collapse>.large-3{width:25%}.medium-margin-collapse>.large-4{width:33.3333333333%}.medium-margin-collapse>.large-5{width:41.6666666667%}.medium-margin-collapse>.large-6{width:50%}.medium-margin-collapse>.large-7{width:58.3333333333%}.medium-margin-collapse>.large-8{width:66.6666666667%}.medium-margin-collapse>.large-9{width:75%}.medium-margin-collapse>.large-10{width:83.3333333333%}.medium-margin-collapse>.large-11{width:91.6666666667%}.medium-margin-collapse>.large-12{width:100%}}@media print,screen and (min-width:40em){.medium-padding-collapse{margin-left:0;margin-right:0}.medium-padding-collapse>.cell{padding-left:0;padding-right:0}}@media print,screen and (min-width:64em){.large-margin-collapse,.large-margin-collapse>.cell{margin-left:0;margin-right:0}.large-margin-collapse>.small-1{width:8.3333333333%}.large-margin-collapse>.small-2{width:16.6666666667%}.large-margin-collapse>.small-3{width:25%}.large-margin-collapse>.small-4{width:33.3333333333%}.large-margin-collapse>.small-5{width:41.6666666667%}.large-margin-collapse>.small-6{width:50%}.large-margin-collapse>.small-7{width:58.3333333333%}.large-margin-collapse>.small-8{width:66.6666666667%}.large-margin-collapse>.small-9{width:75%}.large-margin-collapse>.small-10{width:83.3333333333%}.large-margin-collapse>.small-11{width:91.6666666667%}.large-margin-collapse>.small-12{width:100%}.large-margin-collapse>.medium-1{width:8.3333333333%}.large-margin-collapse>.medium-2{width:16.6666666667%}.large-margin-collapse>.medium-3{width:25%}.large-margin-collapse>.medium-4{width:33.3333333333%}.large-margin-collapse>.medium-5{width:41.6666666667%}.large-margin-collapse>.medium-6{width:50%}.large-margin-collapse>.medium-7{width:58.3333333333%}.large-margin-collapse>.medium-8{width:66.6666666667%}.large-margin-collapse>.medium-9{width:75%}.large-margin-collapse>.medium-10{width:83.3333333333%}.large-margin-collapse>.medium-11{width:91.6666666667%}.large-margin-collapse>.medium-12{width:100%}.large-margin-collapse>.large-1{width:8.3333333333%}.large-margin-collapse>.large-2{width:16.6666666667%}.large-margin-collapse>.large-3{width:25%}.large-margin-collapse>.large-4{width:33.3333333333%}.large-margin-collapse>.large-5{width:41.6666666667%}.large-margin-collapse>.large-6{width:50%}.large-margin-collapse>.large-7{width:58.3333333333%}.large-margin-collapse>.large-8{width:66.6666666667%}.large-margin-collapse>.large-9{width:75%}.large-margin-collapse>.large-10{width:83.3333333333%}.large-margin-collapse>.large-11{width:91.6666666667%}.large-margin-collapse>.large-12{width:100%}.large-padding-collapse{margin-left:0;margin-right:0}.large-padding-collapse>.cell{padding-left:0;padding-right:0}}.small-offset-0{margin-left:0}.grid-margin-x>.small-offset-0{margin-left:.625rem}.small-offset-1{margin-left:8.3333333333%}.grid-margin-x>.small-offset-1{margin-left:calc(8.33333% + .625rem)}.small-offset-2{margin-left:16.6666666667%}.grid-margin-x>.small-offset-2{margin-left:calc(16.66667% + .625rem)}.small-offset-3{margin-left:25%}.grid-margin-x>.small-offset-3{margin-left:calc(25% + .625rem)}.small-offset-4{margin-left:33.3333333333%}.grid-margin-x>.small-offset-4{margin-left:calc(33.33333% + .625rem)}.small-offset-5{margin-left:41.6666666667%}.grid-margin-x>.small-offset-5{margin-left:calc(41.66667% + .625rem)}.small-offset-6{margin-left:50%}.grid-margin-x>.small-offset-6{margin-left:calc(50% + .625rem)}.small-offset-7{margin-left:58.3333333333%}.grid-margin-x>.small-offset-7{margin-left:calc(58.33333% + .625rem)}.small-offset-8{margin-left:66.6666666667%}.grid-margin-x>.small-offset-8{margin-left:calc(66.66667% + .625rem)}.small-offset-9{margin-left:75%}.grid-margin-x>.small-offset-9{margin-left:calc(75% + .625rem)}.small-offset-10{margin-left:83.3333333333%}.grid-margin-x>.small-offset-10{margin-left:calc(83.33333% + .625rem)}.small-offset-11{margin-left:91.6666666667%}.grid-margin-x>.small-offset-11{margin-left:calc(91.66667% + .625rem)}@media print,screen and (min-width:40em){.medium-offset-0{margin-left:0}.grid-margin-x>.medium-offset-0{margin-left:.9375rem}.medium-offset-1{margin-left:8.3333333333%}.grid-margin-x>.medium-offset-1{margin-left:calc(8.33333% + .9375rem)}.medium-offset-2{margin-left:16.6666666667%}.grid-margin-x>.medium-offset-2{margin-left:calc(16.66667% + .9375rem)}.medium-offset-3{margin-left:25%}.grid-margin-x>.medium-offset-3{margin-left:calc(25% + .9375rem)}.medium-offset-4{margin-left:33.3333333333%}.grid-margin-x>.medium-offset-4{margin-left:calc(33.33333% + .9375rem)}.medium-offset-5{margin-left:41.6666666667%}.grid-margin-x>.medium-offset-5{margin-left:calc(41.66667% + .9375rem)}.medium-offset-6{margin-left:50%}.grid-margin-x>.medium-offset-6{margin-left:calc(50% + .9375rem)}.medium-offset-7{margin-left:58.3333333333%}.grid-margin-x>.medium-offset-7{margin-left:calc(58.33333% + .9375rem)}.medium-offset-8{margin-left:66.6666666667%}.grid-margin-x>.medium-offset-8{margin-left:calc(66.66667% + .9375rem)}.medium-offset-9{margin-left:75%}.grid-margin-x>.medium-offset-9{margin-left:calc(75% + .9375rem)}.medium-offset-10{margin-left:83.3333333333%}.grid-margin-x>.medium-offset-10{margin-left:calc(83.33333% + .9375rem)}.medium-offset-11{margin-left:91.6666666667%}.grid-margin-x>.medium-offset-11{margin-left:calc(91.66667% + .9375rem)}}@media print,screen and (min-width:64em){.large-offset-0{margin-left:0}.grid-margin-x>.large-offset-0{margin-left:.9375rem}.large-offset-1{margin-left:8.3333333333%}.grid-margin-x>.large-offset-1{margin-left:calc(8.33333% + .9375rem)}.large-offset-2{margin-left:16.6666666667%}.grid-margin-x>.large-offset-2{margin-left:calc(16.66667% + .9375rem)}.large-offset-3{margin-left:25%}.grid-margin-x>.large-offset-3{margin-left:calc(25% + .9375rem)}.large-offset-4{margin-left:33.3333333333%}.grid-margin-x>.large-offset-4{margin-left:calc(33.33333% + .9375rem)}.large-offset-5{margin-left:41.6666666667%}.grid-margin-x>.large-offset-5{margin-left:calc(41.66667% + .9375rem)}.large-offset-6{margin-left:50%}.grid-margin-x>.large-offset-6{margin-left:calc(50% + .9375rem)}.large-offset-7{margin-left:58.3333333333%}.grid-margin-x>.large-offset-7{margin-left:calc(58.33333% + .9375rem)}.large-offset-8{margin-left:66.6666666667%}.grid-margin-x>.large-offset-8{margin-left:calc(66.66667% + .9375rem)}.large-offset-9{margin-left:75%}.grid-margin-x>.large-offset-9{margin-left:calc(75% + .9375rem)}.large-offset-10{margin-left:83.3333333333%}.grid-margin-x>.large-offset-10{margin-left:calc(83.33333% + .9375rem)}.large-offset-11{margin-left:91.6666666667%}.grid-margin-x>.large-offset-11{margin-left:calc(91.66667% + .9375rem)}}.grid-y{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:column nowrap;-ms-flex-flow:column nowrap;flex-flow:column nowrap}.grid-y>.cell{height:auto;max-height:none}.grid-y>.auto,.grid-y>.shrink{height:auto}.grid-y>.small-1,.grid-y>.small-10,.grid-y>.small-11,.grid-y>.small-12,.grid-y>.small-2,.grid-y>.small-3,.grid-y>.small-4,.grid-y>.small-5,.grid-y>.small-6,.grid-y>.small-7,.grid-y>.small-8,.grid-y>.small-9,.grid-y>.small-full,.grid-y>.small-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}@media print,screen and (min-width:40em){.grid-y>.medium-1,.grid-y>.medium-10,.grid-y>.medium-11,.grid-y>.medium-12,.grid-y>.medium-2,.grid-y>.medium-3,.grid-y>.medium-4,.grid-y>.medium-5,.grid-y>.medium-6,.grid-y>.medium-7,.grid-y>.medium-8,.grid-y>.medium-9,.grid-y>.medium-full,.grid-y>.medium-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}}@media print,screen and (min-width:64em){.grid-y>.large-1,.grid-y>.large-10,.grid-y>.large-11,.grid-y>.large-12,.grid-y>.large-2,.grid-y>.large-3,.grid-y>.large-4,.grid-y>.large-5,.grid-y>.large-6,.grid-y>.large-7,.grid-y>.large-8,.grid-y>.large-9,.grid-y>.large-full,.grid-y>.large-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}}.grid-y>.small-1,.grid-y>.small-10,.grid-y>.small-11,.grid-y>.small-12,.grid-y>.small-2,.grid-y>.small-3,.grid-y>.small-4,.grid-y>.small-5,.grid-y>.small-6,.grid-y>.small-7,.grid-y>.small-8,.grid-y>.small-9{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-y>.small-1{height:8.3333333333%}.grid-y>.small-2{height:16.6666666667%}.grid-y>.small-3{height:25%}.grid-y>.small-4{height:33.3333333333%}.grid-y>.small-5{height:41.6666666667%}.grid-y>.small-6{height:50%}.grid-y>.small-7{height:58.3333333333%}.grid-y>.small-8{height:66.6666666667%}.grid-y>.small-9{height:75%}.grid-y>.small-10{height:83.3333333333%}.grid-y>.small-11{height:91.6666666667%}.grid-y>.small-12{height:100%}@media print,screen and (min-width:40em){.grid-y>.medium-auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;height:auto}.grid-y>.medium-1,.grid-y>.medium-10,.grid-y>.medium-11,.grid-y>.medium-12,.grid-y>.medium-2,.grid-y>.medium-3,.grid-y>.medium-4,.grid-y>.medium-5,.grid-y>.medium-6,.grid-y>.medium-7,.grid-y>.medium-8,.grid-y>.medium-9,.grid-y>.medium-shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-y>.medium-shrink{height:auto}.grid-y>.medium-1{height:8.3333333333%}.grid-y>.medium-2{height:16.6666666667%}.grid-y>.medium-3{height:25%}.grid-y>.medium-4{height:33.3333333333%}.grid-y>.medium-5{height:41.6666666667%}.grid-y>.medium-6{height:50%}.grid-y>.medium-7{height:58.3333333333%}.grid-y>.medium-8{height:66.6666666667%}.grid-y>.medium-9{height:75%}.grid-y>.medium-10{height:83.3333333333%}.grid-y>.medium-11{height:91.6666666667%}.grid-y>.medium-12{height:100%}}@media print,screen and (min-width:64em){.grid-y>.large-auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;height:auto}.grid-y>.large-1,.grid-y>.large-10,.grid-y>.large-11,.grid-y>.large-12,.grid-y>.large-2,.grid-y>.large-3,.grid-y>.large-4,.grid-y>.large-5,.grid-y>.large-6,.grid-y>.large-7,.grid-y>.large-8,.grid-y>.large-9,.grid-y>.large-shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-y>.large-shrink{height:auto}.grid-y>.large-1{height:8.3333333333%}.grid-y>.large-2{height:16.6666666667%}.grid-y>.large-3{height:25%}.grid-y>.large-4{height:33.3333333333%}.grid-y>.large-5{height:41.6666666667%}.grid-y>.large-6{height:50%}.grid-y>.large-7{height:58.3333333333%}.grid-y>.large-8{height:66.6666666667%}.grid-y>.large-9{height:75%}.grid-y>.large-10{height:83.3333333333%}.grid-y>.large-11{height:91.6666666667%}.grid-y>.large-12{height:100%}}.grid-padding-y .grid-padding-y{margin-bottom:-.625rem;margin-top:-.625rem}@media print,screen and (min-width:40em){.grid-padding-y .grid-padding-y{margin-bottom:-.9375rem;margin-top:-.9375rem}}.grid-padding-y>.cell{padding-bottom:.625rem;padding-top:.625rem}@media print,screen and (min-width:40em){.grid-padding-y>.cell{padding-bottom:.9375rem;padding-top:.9375rem}}.grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;overflow:hidden;position:relative;width:100vw}.cell .grid-frame{width:100%}.cell-block{max-width:100%;overflow-x:auto}.cell-block,.cell-block-y{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.cell-block-y{max-height:100%;min-height:100%;overflow-y:auto}.cell-block-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-height:100%}.cell-block-container>.grid-x{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;max-height:100%}@media print,screen and (min-width:40em){.medium-grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;overflow:hidden;position:relative;width:100vw}.cell .medium-grid-frame{width:100%}.medium-cell-block{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;max-width:100%;overflow-x:auto}.medium-cell-block-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-height:100%}.medium-cell-block-container>.grid-x{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;max-height:100%}.medium-cell-block-y{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;max-height:100%;min-height:100%;overflow-y:auto}}@media print,screen and (min-width:64em){.large-grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;overflow:hidden;position:relative;width:100vw}.cell .large-grid-frame{width:100%}.large-cell-block{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;max-width:100%;overflow-x:auto}.large-cell-block-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-height:100%}.large-cell-block-container>.grid-x{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;max-height:100%}.large-cell-block-y{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;max-height:100%;min-height:100%;overflow-y:auto}}.grid-y.grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;height:100vh;overflow:hidden;position:relative;width:auto}@media print,screen and (min-width:40em){.grid-y.medium-grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;height:100vh;overflow:hidden;position:relative;width:auto}}@media print,screen and (min-width:64em){.grid-y.large-grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;height:100vh;overflow:hidden;position:relative;width:auto}}.cell .grid-y.grid-frame{height:100%}@media print,screen and (min-width:40em){.cell .grid-y.medium-grid-frame{height:100%}}@media print,screen and (min-width:64em){.cell .grid-y.large-grid-frame{height:100%}}.grid-margin-y{margin-bottom:-.625rem;margin-top:-.625rem}@media print,screen and (min-width:40em){.grid-margin-y{margin-bottom:-.9375rem;margin-top:-.9375rem}}.grid-margin-y>.cell{height:calc(100% - 1.25rem);margin-bottom:.625rem;margin-top:.625rem}@media print,screen and (min-width:40em){.grid-margin-y>.cell{height:calc(100% - 1.875rem);margin-bottom:.9375rem;margin-top:.9375rem}}.grid-margin-y>.auto,.grid-margin-y>.shrink{height:auto}.grid-margin-y>.small-1{height:calc(8.33333% - 1.25rem)}.grid-margin-y>.small-2{height:calc(16.66667% - 1.25rem)}.grid-margin-y>.small-3{height:calc(25% - 1.25rem)}.grid-margin-y>.small-4{height:calc(33.33333% - 1.25rem)}.grid-margin-y>.small-5{height:calc(41.66667% - 1.25rem)}.grid-margin-y>.small-6{height:calc(50% - 1.25rem)}.grid-margin-y>.small-7{height:calc(58.33333% - 1.25rem)}.grid-margin-y>.small-8{height:calc(66.66667% - 1.25rem)}.grid-margin-y>.small-9{height:calc(75% - 1.25rem)}.grid-margin-y>.small-10{height:calc(83.33333% - 1.25rem)}.grid-margin-y>.small-11{height:calc(91.66667% - 1.25rem)}.grid-margin-y>.small-12{height:calc(100% - 1.25rem)}@media print,screen and (min-width:40em){.grid-margin-y>.auto,.grid-margin-y>.shrink{height:auto}.grid-margin-y>.small-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.small-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.small-3{height:calc(25% - 1.875rem)}.grid-margin-y>.small-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.small-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.small-6{height:calc(50% - 1.875rem)}.grid-margin-y>.small-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.small-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.small-9{height:calc(75% - 1.875rem)}.grid-margin-y>.small-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.small-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.small-12{height:calc(100% - 1.875rem)}.grid-margin-y>.medium-auto,.grid-margin-y>.medium-shrink{height:auto}.grid-margin-y>.medium-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.medium-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.medium-3{height:calc(25% - 1.875rem)}.grid-margin-y>.medium-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.medium-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.medium-6{height:calc(50% - 1.875rem)}.grid-margin-y>.medium-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.medium-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.medium-9{height:calc(75% - 1.875rem)}.grid-margin-y>.medium-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.medium-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.medium-12{height:calc(100% - 1.875rem)}}@media print,screen and (min-width:64em){.grid-margin-y>.large-auto,.grid-margin-y>.large-shrink{height:auto}.grid-margin-y>.large-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.large-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.large-3{height:calc(25% - 1.875rem)}.grid-margin-y>.large-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.large-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.large-6{height:calc(50% - 1.875rem)}.grid-margin-y>.large-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.large-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.large-9{height:calc(75% - 1.875rem)}.grid-margin-y>.large-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.large-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.large-12{height:calc(100% - 1.875rem)}}.grid-frame.grid-margin-y{height:calc(100vh + 1.25rem)}@media print,screen and (min-width:40em){.grid-frame.grid-margin-y{height:calc(100vh + 1.875rem)}}@media print,screen and (min-width:64em){.grid-frame.grid-margin-y{height:calc(100vh + 1.875rem)}}@media print,screen and (min-width:40em){.grid-margin-y.medium-grid-frame{height:calc(100vh + 1.875rem)}}@media print,screen and (min-width:64em){.grid-margin-y.large-grid-frame{height:calc(100vh + 1.875rem)}}.button{-webkit-appearance:none;border:1px solid transparent;border-radius:0;cursor:pointer;display:inline-block;font-family:inherit;font-size:.9rem;line-height:1;margin:0 0 1rem;padding:.85em 1em;text-align:center;-webkit-transition:background-color .25s ease-out,color .25s ease-out;transition:background-color .25s ease-out,color .25s ease-out;vertical-align:middle}[data-whatinput=mouse] .button{outline:0}.button.tiny{font-size:.6rem}.button.small{font-size:.75rem}.button.large{font-size:1.25rem}.button.expanded{display:block;margin-left:0;margin-right:0;width:100%}.button,.button.disabled,.button.disabled:focus,.button.disabled:hover,.button[disabled],.button[disabled]:focus,.button[disabled]:hover{background-color:#1779ba;color:#fefefe}.button:focus,.button:hover{background-color:#14679e;color:#fefefe}.button.primary,.button.primary.disabled,.button.primary.disabled:focus,.button.primary.disabled:hover,.button.primary[disabled],.button.primary[disabled]:focus,.button.primary[disabled]:hover{background-color:#1779ba;color:#fefefe}.button.primary:focus,.button.primary:hover{background-color:#126195;color:#fefefe}.button.secondary,.button.secondary.disabled,.button.secondary.disabled:focus,.button.secondary.disabled:hover,.button.secondary[disabled],.button.secondary[disabled]:focus,.button.secondary[disabled]:hover{background-color:#767676;color:#fefefe}.button.secondary:focus,.button.secondary:hover{background-color:#5e5e5e;color:#fefefe}.button.success,.button.success.disabled,.button.success.disabled:focus,.button.success.disabled:hover,.button.success[disabled],.button.success[disabled]:focus,.button.success[disabled]:hover{background-color:#3adb76;color:#0a0a0a}.button.success:focus,.button.success:hover{background-color:#22bb5b;color:#0a0a0a}.button.warning,.button.warning.disabled,.button.warning.disabled:focus,.button.warning.disabled:hover,.button.warning[disabled],.button.warning[disabled]:focus,.button.warning[disabled]:hover{background-color:#ffae00;color:#0a0a0a}.button.warning:focus,.button.warning:hover{background-color:#cc8b00;color:#0a0a0a}.button.alert,.button.alert.disabled,.button.alert.disabled:focus,.button.alert.disabled:hover,.button.alert[disabled],.button.alert[disabled]:focus,.button.alert[disabled]:hover{background-color:#cc4b37;color:#fefefe}.button.alert:focus,.button.alert:hover{background-color:#a53b2a;color:#fefefe}.button.hollow,.button.hollow.disabled,.button.hollow.disabled:focus,.button.hollow.disabled:hover,.button.hollow:focus,.button.hollow:hover,.button.hollow[disabled],.button.hollow[disabled]:focus,.button.hollow[disabled]:hover{background-color:transparent}.button.hollow,.button.hollow.disabled,.button.hollow.disabled:focus,.button.hollow.disabled:hover,.button.hollow[disabled],.button.hollow[disabled]:focus,.button.hollow[disabled]:hover{border:1px solid #1779ba;color:#1779ba}.button.hollow:focus,.button.hollow:hover{border-color:#0c3d5d;color:#0c3d5d}.button.hollow.primary,.button.hollow.primary.disabled,.button.hollow.primary.disabled:focus,.button.hollow.primary.disabled:hover,.button.hollow.primary[disabled],.button.hollow.primary[disabled]:focus,.button.hollow.primary[disabled]:hover{border:1px solid #1779ba;color:#1779ba}.button.hollow.primary:focus,.button.hollow.primary:hover{border-color:#0c3d5d;color:#0c3d5d}.button.hollow.secondary,.button.hollow.secondary.disabled,.button.hollow.secondary.disabled:focus,.button.hollow.secondary.disabled:hover,.button.hollow.secondary[disabled],.button.hollow.secondary[disabled]:focus,.button.hollow.secondary[disabled]:hover{border:1px solid #767676;color:#767676}.button.hollow.secondary:focus,.button.hollow.secondary:hover{border-color:#3b3b3b;color:#3b3b3b}.button.hollow.success,.button.hollow.success.disabled,.button.hollow.success.disabled:focus,.button.hollow.success.disabled:hover,.button.hollow.success[disabled],.button.hollow.success[disabled]:focus,.button.hollow.success[disabled]:hover{border:1px solid #3adb76;color:#3adb76}.button.hollow.success:focus,.button.hollow.success:hover{border-color:#157539;color:#157539}.button.hollow.warning,.button.hollow.warning.disabled,.button.hollow.warning.disabled:focus,.button.hollow.warning.disabled:hover,.button.hollow.warning[disabled],.button.hollow.warning[disabled]:focus,.button.hollow.warning[disabled]:hover{border:1px solid #ffae00;color:#ffae00}.button.hollow.warning:focus,.button.hollow.warning:hover{border-color:#805700;color:#805700}.button.hollow.alert,.button.hollow.alert.disabled,.button.hollow.alert.disabled:focus,.button.hollow.alert.disabled:hover,.button.hollow.alert[disabled],.button.hollow.alert[disabled]:focus,.button.hollow.alert[disabled]:hover{border:1px solid #cc4b37;color:#cc4b37}.button.hollow.alert:focus,.button.hollow.alert:hover{border-color:#67251a;color:#67251a}.button.clear,.button.clear.disabled,.button.clear.disabled:focus,.button.clear.disabled:hover,.button.clear:focus,.button.clear:hover,.button.clear[disabled],.button.clear[disabled]:focus,.button.clear[disabled]:hover{background-color:transparent;border-color:transparent}.button.clear,.button.clear.disabled,.button.clear.disabled:focus,.button.clear.disabled:hover,.button.clear[disabled],.button.clear[disabled]:focus,.button.clear[disabled]:hover{color:#1779ba}.button.clear:focus,.button.clear:hover{color:#0c3d5d}.button.clear.primary,.button.clear.primary.disabled,.button.clear.primary.disabled:focus,.button.clear.primary.disabled:hover,.button.clear.primary[disabled],.button.clear.primary[disabled]:focus,.button.clear.primary[disabled]:hover{color:#1779ba}.button.clear.primary:focus,.button.clear.primary:hover{color:#0c3d5d}.button.clear.secondary,.button.clear.secondary.disabled,.button.clear.secondary.disabled:focus,.button.clear.secondary.disabled:hover,.button.clear.secondary[disabled],.button.clear.secondary[disabled]:focus,.button.clear.secondary[disabled]:hover{color:#767676}.button.clear.secondary:focus,.button.clear.secondary:hover{color:#3b3b3b}.button.clear.success,.button.clear.success.disabled,.button.clear.success.disabled:focus,.button.clear.success.disabled:hover,.button.clear.success[disabled],.button.clear.success[disabled]:focus,.button.clear.success[disabled]:hover{color:#3adb76}.button.clear.success:focus,.button.clear.success:hover{color:#157539}.button.clear.warning,.button.clear.warning.disabled,.button.clear.warning.disabled:focus,.button.clear.warning.disabled:hover,.button.clear.warning[disabled],.button.clear.warning[disabled]:focus,.button.clear.warning[disabled]:hover{color:#ffae00}.button.clear.warning:focus,.button.clear.warning:hover{color:#805700}.button.clear.alert,.button.clear.alert.disabled,.button.clear.alert.disabled:focus,.button.clear.alert.disabled:hover,.button.clear.alert[disabled],.button.clear.alert[disabled]:focus,.button.clear.alert[disabled]:hover{color:#cc4b37}.button.clear.alert:focus,.button.clear.alert:hover{color:#67251a}.button.disabled,.button[disabled]{cursor:not-allowed;opacity:.25}.button.dropdown:after{border-color:#fefefe transparent transparent;border-style:solid;border-width:.4em .4em 0;content:"";display:block;display:inline-block;float:right;height:0;margin-left:1em;position:relative;top:.4em;width:0}.button.dropdown.clear.primary:after,.button.dropdown.clear:after,.button.dropdown.hollow.primary:after,.button.dropdown.hollow:after{border-top-color:#1779ba}.button.dropdown.clear.secondary:after,.button.dropdown.hollow.secondary:after{border-top-color:#767676}.button.dropdown.clear.success:after,.button.dropdown.hollow.success:after{border-top-color:#3adb76}.button.dropdown.clear.warning:after,.button.dropdown.hollow.warning:after{border-top-color:#ffae00}.button.dropdown.clear.alert:after,.button.dropdown.hollow.alert:after{border-top-color:#cc4b37}.button.arrow-only:after{float:none;margin-left:0;top:-.1em}a.button:focus,a.button:hover{text-decoration:none}.button-group{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-box-flex:1;-ms-flex-positive:1;-webkit-align-items:stretch;align-items:stretch;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-bottom:1rem}.button-group:after,.button-group:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.button-group:after{clear:both}.button-group:after,.button-group:before{display:none}.button-group .button{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;font-size:.9rem;margin:0 1px 1px 0}.button-group .button:last-child{margin-right:0}.button-group.tiny .button{font-size:.6rem}.button-group.small .button{font-size:.75rem}.button-group.large .button{font-size:1.25rem}.button-group.expanded .button{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}.button-group.primary .button,.button-group.primary .button.disabled,.button-group.primary .button.disabled:focus,.button-group.primary .button.disabled:hover,.button-group.primary .button[disabled],.button-group.primary .button[disabled]:focus,.button-group.primary .button[disabled]:hover{background-color:#1779ba;color:#fefefe}.button-group.primary .button:focus,.button-group.primary .button:hover{background-color:#126195;color:#fefefe}.button-group.secondary .button,.button-group.secondary .button.disabled,.button-group.secondary .button.disabled:focus,.button-group.secondary .button.disabled:hover,.button-group.secondary .button[disabled],.button-group.secondary .button[disabled]:focus,.button-group.secondary .button[disabled]:hover{background-color:#767676;color:#fefefe}.button-group.secondary .button:focus,.button-group.secondary .button:hover{background-color:#5e5e5e;color:#fefefe}.button-group.success .button,.button-group.success .button.disabled,.button-group.success .button.disabled:focus,.button-group.success .button.disabled:hover,.button-group.success .button[disabled],.button-group.success .button[disabled]:focus,.button-group.success .button[disabled]:hover{background-color:#3adb76;color:#0a0a0a}.button-group.success .button:focus,.button-group.success .button:hover{background-color:#22bb5b;color:#0a0a0a}.button-group.warning .button,.button-group.warning .button.disabled,.button-group.warning .button.disabled:focus,.button-group.warning .button.disabled:hover,.button-group.warning .button[disabled],.button-group.warning .button[disabled]:focus,.button-group.warning .button[disabled]:hover{background-color:#ffae00;color:#0a0a0a}.button-group.warning .button:focus,.button-group.warning .button:hover{background-color:#cc8b00;color:#0a0a0a}.button-group.alert .button,.button-group.alert .button.disabled,.button-group.alert .button.disabled:focus,.button-group.alert .button.disabled:hover,.button-group.alert .button[disabled],.button-group.alert .button[disabled]:focus,.button-group.alert .button[disabled]:hover{background-color:#cc4b37;color:#fefefe}.button-group.alert .button:focus,.button-group.alert .button:hover{background-color:#a53b2a;color:#fefefe}.button-group.hollow .button,.button-group.hollow .button.disabled,.button-group.hollow .button.disabled:focus,.button-group.hollow .button.disabled:hover,.button-group.hollow .button:focus,.button-group.hollow .button:hover,.button-group.hollow .button[disabled],.button-group.hollow .button[disabled]:focus,.button-group.hollow .button[disabled]:hover{background-color:transparent}.button-group.hollow .button,.button-group.hollow .button.disabled,.button-group.hollow .button.disabled:focus,.button-group.hollow .button.disabled:hover,.button-group.hollow .button[disabled],.button-group.hollow .button[disabled]:focus,.button-group.hollow .button[disabled]:hover{border:1px solid #1779ba;color:#1779ba}.button-group.hollow .button:focus,.button-group.hollow .button:hover{border-color:#0c3d5d;color:#0c3d5d}.button-group.hollow .button.primary,.button-group.hollow .button.primary.disabled,.button-group.hollow .button.primary.disabled:focus,.button-group.hollow .button.primary.disabled:hover,.button-group.hollow .button.primary[disabled],.button-group.hollow .button.primary[disabled]:focus,.button-group.hollow .button.primary[disabled]:hover,.button-group.hollow.primary .button,.button-group.hollow.primary .button.disabled,.button-group.hollow.primary .button.disabled:focus,.button-group.hollow.primary .button.disabled:hover,.button-group.hollow.primary .button[disabled],.button-group.hollow.primary .button[disabled]:focus,.button-group.hollow.primary .button[disabled]:hover{border:1px solid #1779ba;color:#1779ba}.button-group.hollow .button.primary:focus,.button-group.hollow .button.primary:hover,.button-group.hollow.primary .button:focus,.button-group.hollow.primary .button:hover{border-color:#0c3d5d;color:#0c3d5d}.button-group.hollow .button.secondary,.button-group.hollow .button.secondary.disabled,.button-group.hollow .button.secondary.disabled:focus,.button-group.hollow .button.secondary.disabled:hover,.button-group.hollow .button.secondary[disabled],.button-group.hollow .button.secondary[disabled]:focus,.button-group.hollow .button.secondary[disabled]:hover,.button-group.hollow.secondary .button,.button-group.hollow.secondary .button.disabled,.button-group.hollow.secondary .button.disabled:focus,.button-group.hollow.secondary .button.disabled:hover,.button-group.hollow.secondary .button[disabled],.button-group.hollow.secondary .button[disabled]:focus,.button-group.hollow.secondary .button[disabled]:hover{border:1px solid #767676;color:#767676}.button-group.hollow .button.secondary:focus,.button-group.hollow .button.secondary:hover,.button-group.hollow.secondary .button:focus,.button-group.hollow.secondary .button:hover{border-color:#3b3b3b;color:#3b3b3b}.button-group.hollow .button.success,.button-group.hollow .button.success.disabled,.button-group.hollow .button.success.disabled:focus,.button-group.hollow .button.success.disabled:hover,.button-group.hollow .button.success[disabled],.button-group.hollow .button.success[disabled]:focus,.button-group.hollow .button.success[disabled]:hover,.button-group.hollow.success .button,.button-group.hollow.success .button.disabled,.button-group.hollow.success .button.disabled:focus,.button-group.hollow.success .button.disabled:hover,.button-group.hollow.success .button[disabled],.button-group.hollow.success .button[disabled]:focus,.button-group.hollow.success .button[disabled]:hover{border:1px solid #3adb76;color:#3adb76}.button-group.hollow .button.success:focus,.button-group.hollow .button.success:hover,.button-group.hollow.success .button:focus,.button-group.hollow.success .button:hover{border-color:#157539;color:#157539}.button-group.hollow .button.warning,.button-group.hollow .button.warning.disabled,.button-group.hollow .button.warning.disabled:focus,.button-group.hollow .button.warning.disabled:hover,.button-group.hollow .button.warning[disabled],.button-group.hollow .button.warning[disabled]:focus,.button-group.hollow .button.warning[disabled]:hover,.button-group.hollow.warning .button,.button-group.hollow.warning .button.disabled,.button-group.hollow.warning .button.disabled:focus,.button-group.hollow.warning .button.disabled:hover,.button-group.hollow.warning .button[disabled],.button-group.hollow.warning .button[disabled]:focus,.button-group.hollow.warning .button[disabled]:hover{border:1px solid #ffae00;color:#ffae00}.button-group.hollow .button.warning:focus,.button-group.hollow .button.warning:hover,.button-group.hollow.warning .button:focus,.button-group.hollow.warning .button:hover{border-color:#805700;color:#805700}.button-group.hollow .button.alert,.button-group.hollow .button.alert.disabled,.button-group.hollow .button.alert.disabled:focus,.button-group.hollow .button.alert.disabled:hover,.button-group.hollow .button.alert[disabled],.button-group.hollow .button.alert[disabled]:focus,.button-group.hollow .button.alert[disabled]:hover,.button-group.hollow.alert .button,.button-group.hollow.alert .button.disabled,.button-group.hollow.alert .button.disabled:focus,.button-group.hollow.alert .button.disabled:hover,.button-group.hollow.alert .button[disabled],.button-group.hollow.alert .button[disabled]:focus,.button-group.hollow.alert .button[disabled]:hover{border:1px solid #cc4b37;color:#cc4b37}.button-group.hollow .button.alert:focus,.button-group.hollow .button.alert:hover,.button-group.hollow.alert .button:focus,.button-group.hollow.alert .button:hover{border-color:#67251a;color:#67251a}.button-group.clear .button,.button-group.clear .button.disabled,.button-group.clear .button.disabled:focus,.button-group.clear .button.disabled:hover,.button-group.clear .button:focus,.button-group.clear .button:hover,.button-group.clear .button[disabled],.button-group.clear .button[disabled]:focus,.button-group.clear .button[disabled]:hover{background-color:transparent;border-color:transparent}.button-group.clear .button,.button-group.clear .button.disabled,.button-group.clear .button.disabled:focus,.button-group.clear .button.disabled:hover,.button-group.clear .button[disabled],.button-group.clear .button[disabled]:focus,.button-group.clear .button[disabled]:hover{color:#1779ba}.button-group.clear .button:focus,.button-group.clear .button:hover{color:#0c3d5d}.button-group.clear .button.primary,.button-group.clear .button.primary.disabled,.button-group.clear .button.primary.disabled:focus,.button-group.clear .button.primary.disabled:hover,.button-group.clear .button.primary[disabled],.button-group.clear .button.primary[disabled]:focus,.button-group.clear .button.primary[disabled]:hover,.button-group.clear.primary .button,.button-group.clear.primary .button.disabled,.button-group.clear.primary .button.disabled:focus,.button-group.clear.primary .button.disabled:hover,.button-group.clear.primary .button[disabled],.button-group.clear.primary .button[disabled]:focus,.button-group.clear.primary .button[disabled]:hover{color:#1779ba}.button-group.clear .button.primary:focus,.button-group.clear .button.primary:hover,.button-group.clear.primary .button:focus,.button-group.clear.primary .button:hover{color:#0c3d5d}.button-group.clear .button.secondary,.button-group.clear .button.secondary.disabled,.button-group.clear .button.secondary.disabled:focus,.button-group.clear .button.secondary.disabled:hover,.button-group.clear .button.secondary[disabled],.button-group.clear .button.secondary[disabled]:focus,.button-group.clear .button.secondary[disabled]:hover,.button-group.clear.secondary .button,.button-group.clear.secondary .button.disabled,.button-group.clear.secondary .button.disabled:focus,.button-group.clear.secondary .button.disabled:hover,.button-group.clear.secondary .button[disabled],.button-group.clear.secondary .button[disabled]:focus,.button-group.clear.secondary .button[disabled]:hover{color:#767676}.button-group.clear .button.secondary:focus,.button-group.clear .button.secondary:hover,.button-group.clear.secondary .button:focus,.button-group.clear.secondary .button:hover{color:#3b3b3b}.button-group.clear .button.success,.button-group.clear .button.success.disabled,.button-group.clear .button.success.disabled:focus,.button-group.clear .button.success.disabled:hover,.button-group.clear .button.success[disabled],.button-group.clear .button.success[disabled]:focus,.button-group.clear .button.success[disabled]:hover,.button-group.clear.success .button,.button-group.clear.success .button.disabled,.button-group.clear.success .button.disabled:focus,.button-group.clear.success .button.disabled:hover,.button-group.clear.success .button[disabled],.button-group.clear.success .button[disabled]:focus,.button-group.clear.success .button[disabled]:hover{color:#3adb76}.button-group.clear .button.success:focus,.button-group.clear .button.success:hover,.button-group.clear.success .button:focus,.button-group.clear.success .button:hover{color:#157539}.button-group.clear .button.warning,.button-group.clear .button.warning.disabled,.button-group.clear .button.warning.disabled:focus,.button-group.clear .button.warning.disabled:hover,.button-group.clear .button.warning[disabled],.button-group.clear .button.warning[disabled]:focus,.button-group.clear .button.warning[disabled]:hover,.button-group.clear.warning .button,.button-group.clear.warning .button.disabled,.button-group.clear.warning .button.disabled:focus,.button-group.clear.warning .button.disabled:hover,.button-group.clear.warning .button[disabled],.button-group.clear.warning .button[disabled]:focus,.button-group.clear.warning .button[disabled]:hover{color:#ffae00}.button-group.clear .button.warning:focus,.button-group.clear .button.warning:hover,.button-group.clear.warning .button:focus,.button-group.clear.warning .button:hover{color:#805700}.button-group.clear .button.alert,.button-group.clear .button.alert.disabled,.button-group.clear .button.alert.disabled:focus,.button-group.clear .button.alert.disabled:hover,.button-group.clear .button.alert[disabled],.button-group.clear .button.alert[disabled]:focus,.button-group.clear .button.alert[disabled]:hover,.button-group.clear.alert .button,.button-group.clear.alert .button.disabled,.button-group.clear.alert .button.disabled:focus,.button-group.clear.alert .button.disabled:hover,.button-group.clear.alert .button[disabled],.button-group.clear.alert .button[disabled]:focus,.button-group.clear.alert .button[disabled]:hover{color:#cc4b37}.button-group.clear .button.alert:focus,.button-group.clear .button.alert:hover,.button-group.clear.alert .button:focus,.button-group.clear.alert .button:hover{color:#67251a}.button-group.no-gaps .button{margin-right:-.0625rem}.button-group.no-gaps .button+.button{border-left-color:transparent}.button-group.stacked,.button-group.stacked-for-medium,.button-group.stacked-for-small{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.button-group.stacked .button,.button-group.stacked-for-medium .button,.button-group.stacked-for-small .button{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%}.button-group.stacked .button:last-child,.button-group.stacked-for-medium .button:last-child,.button-group.stacked-for-small .button:last-child{margin-bottom:0}.button-group.stacked-for-medium.expanded .button,.button-group.stacked-for-small.expanded .button,.button-group.stacked.expanded .button{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}@media print,screen and (min-width:40em){.button-group.stacked-for-small .button{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;margin-bottom:0}}@media print,screen and (min-width:64em){.button-group.stacked-for-medium .button{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;margin-bottom:0}}@media print,screen and (max-width:39.99875em){.button-group.stacked-for-small.expanded{display:block}.button-group.stacked-for-small.expanded .button{display:block;margin-right:0}}@media print,screen and (max-width:63.99875em){.button-group.stacked-for-medium.expanded{display:block}.button-group.stacked-for-medium.expanded .button{display:block;margin-right:0}}.close-button{color:#8a8a8a;cursor:pointer;position:absolute;z-index:10}[data-whatinput=mouse] .close-button{outline:0}.close-button:focus,.close-button:hover{color:#0a0a0a}.close-button.small{font-size:1.5em;line-height:1;right:.66rem;top:.33em}.close-button,.close-button.medium{font-size:2em;line-height:1;right:1rem;top:.5rem}.label{border-radius:0;cursor:default;display:inline-block;font-size:.8rem;line-height:1;padding:.33333rem .5rem;white-space:nowrap}.label,.label.primary{background:#1779ba;color:#fefefe}.label.secondary{background:#767676;color:#fefefe}.label.success{background:#3adb76;color:#0a0a0a}.label.warning{background:#ffae00;color:#0a0a0a}.label.alert{background:#cc4b37;color:#fefefe}.progress{background-color:#cacaca;border-radius:0;height:1rem;margin-bottom:1rem}.progress.primary .progress-meter{background-color:#1779ba}.progress.secondary .progress-meter{background-color:#767676}.progress.success .progress-meter{background-color:#3adb76}.progress.warning .progress-meter{background-color:#ffae00}.progress.alert .progress-meter{background-color:#cc4b37}.progress-meter{background-color:#1779ba;display:block;height:100%;position:relative;width:0}.progress-meter-text{color:#fefefe;font-size:.75rem;font-weight:700;left:50%;margin:0;position:absolute;top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);white-space:nowrap}.slider{background-color:#e6e6e6;cursor:pointer;height:.5rem;margin-bottom:2.25rem;margin-top:1.25rem;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.slider-fill{background-color:#cacaca;display:inline-block;height:.5rem;left:0;max-width:100%;position:absolute;top:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.slider-fill.is-dragging{-webkit-transition:all 0s linear;transition:all 0s linear}.slider-handle{background-color:#1779ba;border-radius:0;cursor:-webkit-grab;cursor:grab;display:inline-block;height:1.4rem;left:0;position:absolute;top:50%;-ms-touch-action:manipulation;touch-action:manipulation;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;width:1.4rem;z-index:1}[data-whatinput=mouse] .slider-handle{outline:0}.slider-handle:hover{background-color:#14679e}.slider-handle.is-dragging{cursor:-webkit-grabbing;cursor:grabbing;-webkit-transition:all 0s linear;transition:all 0s linear}.slider.disabled,.slider[disabled]{cursor:not-allowed;opacity:.25}.slider.vertical{display:inline-block;height:12.5rem;margin:0 1.25rem;-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1);width:.5rem}.slider.vertical .slider-fill{max-height:100%;top:0;width:.5rem}.slider.vertical .slider-handle{height:1.4rem;left:50%;position:absolute;top:0;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:1.4rem}.switch{color:#fefefe;font-size:.875rem;font-weight:700;height:2rem;margin-bottom:1rem;outline:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch-input{margin-bottom:0;opacity:0;position:absolute}.switch-paddle{background:#cacaca;border-radius:0;color:inherit;cursor:pointer;display:block;font-weight:inherit;height:2rem;position:relative;-webkit-transition:all .25s ease-out;transition:all .25s ease-out;width:4rem}input+.switch-paddle{margin:0}.switch-paddle:after{background:#fefefe;border-radius:0;content:"";display:block;height:1.5rem;left:.25rem;position:absolute;top:.25rem;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:all .25s ease-out;transition:all .25s ease-out;width:1.5rem}input:checked~.switch-paddle{background:#1779ba}input:checked~.switch-paddle:after{left:2.25rem}input:disabled~.switch-paddle{cursor:not-allowed;opacity:.5}[data-whatinput=mouse] input:focus~.switch-paddle{outline:0}.switch-active,.switch-inactive{position:absolute;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.switch-active{display:none;left:8%}input:checked+label>.switch-active{display:block}.switch-inactive{right:15%}input:checked+label>.switch-inactive{display:none}.switch.tiny{height:1.5rem}.switch.tiny .switch-paddle{font-size:.625rem;height:1.5rem;width:3rem}.switch.tiny .switch-paddle:after{height:1rem;left:.25rem;top:.25rem;width:1rem}.switch.tiny input:checked~.switch-paddle:after{left:1.75rem}.switch.small{height:1.75rem}.switch.small .switch-paddle{font-size:.75rem;height:1.75rem;width:3.5rem}.switch.small .switch-paddle:after{height:1.25rem;left:.25rem;top:.25rem;width:1.25rem}.switch.small input:checked~.switch-paddle:after{left:2rem}.switch.large{height:2.5rem}.switch.large .switch-paddle{font-size:1rem;height:2.5rem;width:5rem}.switch.large .switch-paddle:after{height:2rem;left:.25rem;top:.25rem;width:2rem}.switch.large input:checked~.switch-paddle:after{left:2.75rem}table{border-collapse:collapse;border-radius:0;margin-bottom:1rem;width:100%}tbody,tfoot,thead{background-color:#fefefe;border:1px solid #f1f1f1}caption{font-weight:700;padding:.5rem .625rem .625rem}thead{background:#f8f8f8}tfoot,thead{color:#0a0a0a}tfoot{background:#f1f1f1}tfoot tr,thead tr{background:0 0}tfoot td,tfoot th,thead td,thead th{font-weight:700;padding:.5rem .625rem .625rem;text-align:left}tbody td,tbody th{padding:.5rem .625rem .625rem}tbody tr:nth-child(2n){background-color:#f1f1f1;border-bottom:0}table.unstriped tbody{background-color:#fefefe}table.unstriped tbody tr{background-color:#fefefe;border-bottom:1px solid #f1f1f1}@media print,screen and (max-width:63.99875em){table.stack tfoot,table.stack thead{display:none}table.stack td,table.stack th,table.stack tr{display:block}table.stack td{border-top:0}}table.scroll{display:block;overflow-x:auto;width:100%}table.hover thead tr:hover{background-color:#f3f3f3}table.hover tfoot tr:hover{background-color:#ececec}table.hover tbody tr:hover{background-color:#f9f9f9}table.hover:not(.unstriped) tr:nth-of-type(2n):hover{background-color:#ececec}.table-scroll{overflow-x:auto}.badge{border-radius:50%;display:inline-block;font-size:.6rem;min-width:2.1em;padding:.3em;text-align:center}.badge,.badge.primary{background:#1779ba;color:#fefefe}.badge.secondary{background:#767676;color:#fefefe}.badge.success{background:#3adb76;color:#0a0a0a}.badge.warning{background:#ffae00;color:#0a0a0a}.badge.alert{background:#cc4b37;color:#fefefe}.breadcrumbs{list-style:none;margin:0 0 1rem}.breadcrumbs:after,.breadcrumbs:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.breadcrumbs:after{clear:both}.breadcrumbs li{color:#0a0a0a;cursor:default;float:left;font-size:.6875rem;text-transform:uppercase}.breadcrumbs li:not(:last-child):after{color:#cacaca;content:"/";margin:0 .75rem;opacity:1;position:relative}.breadcrumbs a{color:#1779ba}.breadcrumbs a:hover{text-decoration:underline}.breadcrumbs .disabled{color:#cacaca;cursor:not-allowed}.callout{background-color:#fff;border:1px solid hsla(0,0%,4%,.25);border-radius:0;color:#0a0a0a;margin:0 0 1rem;padding:1rem;position:relative}.callout>:first-child{margin-top:0}.callout>:last-child{margin-bottom:0}.callout.primary{background-color:#d7ecfa;color:#0a0a0a}.callout.secondary{background-color:#eaeaea;color:#0a0a0a}.callout.success{background-color:#e1faea;color:#0a0a0a}.callout.warning{background-color:#fff3d9;color:#0a0a0a}.callout.alert{background-color:#f7e4e1;color:#0a0a0a}.callout.small{padding:.5rem}.callout.large{padding:3rem}.card{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-box-flex:1;-ms-flex-positive:1;background:#fefefe;border:1px solid #e6e6e6;border-radius:0;-webkit-box-shadow:none;box-shadow:none;color:#0a0a0a;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-grow:1;flex-grow:1;margin-bottom:1rem;overflow:hidden}.card>:last-child{margin-bottom:0}.card-divider{-webkit-box-flex:0;background:#e6e6e6;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;padding:1rem}.card-divider>:last-child{margin-bottom:0}.card-section{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;padding:1rem}.card-section>:last-child{margin-bottom:0}.card-image{min-height:1px}.dropdown-pane{background-color:#fefefe;border:1px solid #cacaca;border-radius:0;display:none;font-size:1rem;padding:1rem;position:absolute;visibility:hidden;width:300px;z-index:10}.dropdown-pane.is-opening{display:block}.dropdown-pane.is-open{display:block;visibility:visible}.dropdown-pane.tiny{width:100px}.dropdown-pane.small{width:200px}.dropdown-pane.large{width:400px}.pagination{margin-bottom:1rem;margin-left:0}.pagination:after,.pagination:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.pagination:after{clear:both}.pagination li{border-radius:0;display:none;font-size:.875rem;margin-right:.0625rem}.pagination li:first-child,.pagination li:last-child{display:inline-block}@media print,screen and (min-width:40em){.pagination li{display:inline-block}}.pagination a,.pagination button{border-radius:0;color:#0a0a0a;display:block;padding:.1875rem .625rem}.pagination a:hover,.pagination button:hover{background:#e6e6e6}.pagination .current{background:#1779ba;color:#fefefe;cursor:default;padding:.1875rem .625rem}.pagination .disabled{color:#cacaca;cursor:not-allowed;padding:.1875rem .625rem}.pagination .disabled:hover{background:0 0}.pagination .ellipsis:after{color:#0a0a0a;content:"…";padding:.1875rem .625rem}.pagination-previous a:before,.pagination-previous.disabled:before{content:"«";display:inline-block;margin-right:.5rem}.pagination-next a:after,.pagination-next.disabled:after{content:"»";display:inline-block;margin-left:.5rem}.has-tip{border-bottom:1px dotted #8a8a8a;cursor:help;display:inline-block;font-weight:700;position:relative}.tooltip{background-color:#0a0a0a;border-radius:0;color:#fefefe;font-size:80%;max-width:10rem;padding:.75rem;top:calc(100% + .6495rem);z-index:1200}.tooltip,.tooltip:before{position:absolute}.tooltip.bottom:before{border-color:transparent transparent #0a0a0a;border-style:solid;border-width:0 .75rem .75rem;bottom:100%;content:"";display:block;height:0;width:0}.tooltip.bottom.align-center:before{left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.tooltip.top:before{border-color:#0a0a0a transparent transparent;border-style:solid;border-width:.75rem .75rem 0;bottom:auto;content:"";display:block;height:0;top:100%;width:0}.tooltip.top.align-center:before{left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.tooltip.left:before{border-color:transparent transparent transparent #0a0a0a;border-style:solid;border-width:.75rem 0 .75rem .75rem;content:"";display:block;height:0;left:100%;width:0}.tooltip.left.align-center:before{bottom:auto;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.tooltip.right:before{border-color:transparent #0a0a0a transparent transparent;border-style:solid;border-width:.75rem .75rem .75rem 0;content:"";display:block;height:0;left:auto;right:100%;width:0}.tooltip.right.align-center:before{bottom:auto;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.tooltip.align-top:before{bottom:auto;top:10%}.tooltip.align-bottom:before{bottom:10%;top:auto}.tooltip.align-left:before{left:10%;right:auto}.tooltip.align-right:before{left:auto;right:10%}.accordion{background:#fefefe;list-style-type:none;margin-left:0}.accordion[disabled] .accordion-title{cursor:not-allowed}.accordion-item:first-child>:first-child,.accordion-item:last-child>:last-child{border-radius:0}.accordion-title{border:1px solid #e6e6e6;border-bottom:0;color:#1779ba;display:block;font-size:.75rem;line-height:1;padding:1.25rem 1rem;position:relative}:last-child:not(.is-active)>.accordion-title{border-bottom:1px solid #e6e6e6;border-radius:0}.accordion-title:focus,.accordion-title:hover{background-color:#e6e6e6}.accordion-title:before{content:"+";margin-top:-.5rem;position:absolute;right:1rem;top:50%}.is-active>.accordion-title:before{content:"–"}.accordion-content{background-color:#fefefe;border:1px solid #e6e6e6;border-bottom:0;color:#0a0a0a;display:none;padding:1rem}:last-child>.accordion-content:last-child{border-bottom:1px solid #e6e6e6}.media-object{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;margin-bottom:1rem}.media-object img{max-width:none}@media print,screen and (max-width:39.99875em){.media-object.stack-for-small{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}}.media-object-section{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.media-object-section:first-child{padding-right:1rem}.media-object-section:last-child:not(:nth-child(2)){padding-left:1rem}.media-object-section>:last-child{margin-bottom:0}@media print,screen and (max-width:39.99875em){.stack-for-small .media-object-section{-ms-flex-preferred-size:100%;-webkit-flex-basis:100%;flex-basis:100%;max-width:100%;padding:0 0 1rem}.stack-for-small .media-object-section img{width:100%}}.media-object-section.main-section{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}.orbit,.orbit-container{position:relative}.orbit-container{height:0;list-style:none;margin:0;overflow:hidden}.orbit-slide{position:absolute;width:100%}.orbit-slide.no-motionui.is-active{left:0;top:0}.orbit-figure{margin:0}.orbit-image{margin:0;max-width:100%;width:100%}.orbit-caption{background-color:hsla(0,0%,4%,.5);bottom:0;margin-bottom:0;width:100%}.orbit-caption,.orbit-next,.orbit-previous{color:#fefefe;padding:1rem;position:absolute}.orbit-next,.orbit-previous{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);z-index:10}[data-whatinput=mouse] .orbit-next,[data-whatinput=mouse] .orbit-previous{outline:0}.orbit-next:active,.orbit-next:focus,.orbit-next:hover,.orbit-previous:active,.orbit-previous:focus,.orbit-previous:hover{background-color:hsla(0,0%,4%,.5)}.orbit-previous{left:0}.orbit-next{left:auto;right:0}.orbit-bullets{margin-bottom:.8rem;margin-top:.8rem;position:relative;text-align:center}[data-whatinput=mouse] .orbit-bullets{outline:0}.orbit-bullets button{background-color:#cacaca;border-radius:50%;height:1.2rem;margin:.1rem;width:1.2rem}.orbit-bullets button.is-active,.orbit-bullets button:hover{background-color:#8a8a8a}.flex-video,.responsive-embed{height:0;margin-bottom:1rem;overflow:hidden;padding-bottom:75%;position:relative}.flex-video embed,.flex-video iframe,.flex-video object,.flex-video video,.responsive-embed embed,.responsive-embed iframe,.responsive-embed object,.responsive-embed video{height:100%;left:0;position:absolute;top:0;width:100%}.flex-video.widescreen,.responsive-embed.widescreen{padding-bottom:56.25%}.tabs{background:#fefefe;border:1px solid #e6e6e6;list-style-type:none;margin:0}.tabs:after,.tabs:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.tabs:after{clear:both}.tabs.vertical>li{display:block;float:none;width:auto}.tabs.simple>li>a{padding:0}.tabs.simple>li>a:hover{background:0 0}.tabs.primary{background:#1779ba}.tabs.primary>li>a{color:#fefefe}.tabs.primary>li>a:focus,.tabs.primary>li>a:hover{background:#1673b1}.tabs-title{float:left}.tabs-title>a{color:#1779ba;display:block;font-size:.75rem;line-height:1;padding:1.25rem 1.5rem}[data-whatinput=mouse] .tabs-title>a{outline:0}.tabs-title>a:hover{background:#fefefe;color:#1468a0}.tabs-title>a:focus,.tabs-title>a[aria-selected=true]{background:#e6e6e6;color:#1779ba}.tabs-content{background:#fefefe;border:1px solid #e6e6e6;border-top:0;color:#0a0a0a;-webkit-transition:all .5s ease;transition:all .5s ease}.tabs-content.vertical{border:1px solid #e6e6e6;border-left:0}.tabs-panel{display:none;padding:1rem}.tabs-panel.is-active{display:block}.thumbnail{border:4px solid #fefefe;border-radius:0;-webkit-box-shadow:0 0 0 1px hsla(0,0%,4%,.2);box-shadow:0 0 0 1px hsla(0,0%,4%,.2);display:inline-block;line-height:0;margin-bottom:1rem;max-width:100%}a.thumbnail{-webkit-transition:-webkit-box-shadow .2s ease-out;transition:-webkit-box-shadow .2s ease-out;transition:box-shadow .2s ease-out;transition:box-shadow .2s ease-out,-webkit-box-shadow .2s ease-out}a.thumbnail:focus,a.thumbnail:hover{-webkit-box-shadow:0 0 6px 1px rgba(23,121,186,.5);box-shadow:0 0 6px 1px rgba(23,121,186,.5)}a.thumbnail image{-webkit-box-shadow:none;box-shadow:none}.menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;list-style:none;margin:0;padding:0;position:relative}[data-whatinput=mouse] .menu li{outline:0}.menu .button,.menu a{display:block;line-height:1;padding:.7rem 1rem;text-decoration:none}.menu a,.menu button,.menu input,.menu select{margin-bottom:0}.menu input{display:inline-block}.menu,.menu.horizontal{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.menu.vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.menu.vertical.icon-bottom li a i,.menu.vertical.icon-bottom li a img,.menu.vertical.icon-bottom li a svg,.menu.vertical.icon-top li a i,.menu.vertical.icon-top li a img,.menu.vertical.icon-top li a svg{text-align:left}.menu.expanded li{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}.menu.expanded.icon-bottom li a i,.menu.expanded.icon-bottom li a img,.menu.expanded.icon-bottom li a svg,.menu.expanded.icon-top li a i,.menu.expanded.icon-top li a img,.menu.expanded.icon-top li a svg{text-align:left}.menu.simple{-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center}.menu.simple li+li{margin-left:1rem}.menu.simple a{padding:0}@media print,screen and (min-width:40em){.menu.medium-horizontal{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.menu.medium-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.menu.medium-expanded li,.menu.medium-simple li{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}}@media print,screen and (min-width:64em){.menu.large-horizontal{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.menu.large-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.menu.large-expanded li,.menu.large-simple li{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}}.menu.nested{margin-left:1rem;margin-right:0}.menu.icon-bottom a,.menu.icon-left a,.menu.icon-right a,.menu.icon-top a,.menu.icons a{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.menu.icon-left li a,.menu.nested.icon-left li a{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap}.menu.icon-left li a i,.menu.icon-left li a img,.menu.icon-left li a svg,.menu.nested.icon-left li a i,.menu.nested.icon-left li a img,.menu.nested.icon-left li a svg{margin-right:.25rem}.menu.icon-right li a,.menu.nested.icon-right li a{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap}.menu.icon-right li a i,.menu.icon-right li a img,.menu.icon-right li a svg,.menu.nested.icon-right li a i,.menu.nested.icon-right li a img,.menu.nested.icon-right li a svg{margin-left:.25rem}.menu.icon-top li a,.menu.nested.icon-top li a{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-flow:column nowrap;-ms-flex-flow:column nowrap;flex-flow:column nowrap}.menu.icon-top li a i,.menu.icon-top li a img,.menu.icon-top li a svg,.menu.nested.icon-top li a i,.menu.nested.icon-top li a img,.menu.nested.icon-top li a svg{-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;margin-bottom:.25rem;text-align:center}.menu.icon-bottom li a,.menu.nested.icon-bottom li a{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-flow:column nowrap;-ms-flex-flow:column nowrap;flex-flow:column nowrap}.menu.icon-bottom li a i,.menu.icon-bottom li a img,.menu.icon-bottom li a svg,.menu.nested.icon-bottom li a i,.menu.nested.icon-bottom li a img,.menu.nested.icon-bottom li a svg{-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;margin-bottom:.25rem;text-align:center}.menu .active>a,.menu .is-active>a{background:#1779ba;color:#fefefe}.menu.align-left{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.menu.align-right li{-webkit-box-pack:end;-ms-flex-pack:end;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:flex-end;justify-content:flex-end}.menu.align-right li .submenu li{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.menu.align-right.vertical li{display:block;text-align:right}.menu.align-right.icon-bottom li a i,.menu.align-right.icon-bottom li a img,.menu.align-right.icon-bottom li a svg,.menu.align-right.icon-top li a i,.menu.align-right.icon-top li a img,.menu.align-right.icon-top li a svg,.menu.align-right.vertical li .submenu li{text-align:right}.menu.align-right .nested{margin-left:0;margin-right:1rem}.menu.align-center li{-webkit-box-pack:center;-ms-flex-pack:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;justify-content:center}.menu.align-center li .submenu li{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.menu .menu-text{color:inherit;font-weight:700;line-height:1;padding:.7rem 1rem}.menu-centered>.menu,.menu-centered>.menu li{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center}.menu-centered>.menu li{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.menu-centered>.menu li .submenu li{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.no-js [data-responsive-menu] ul{display:none}.menu-icon{cursor:pointer;display:inline-block;height:16px;position:relative;vertical-align:middle;width:20px}.menu-icon:after{background:#fefefe;-webkit-box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe;box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe;content:"";display:block;height:2px;left:0;position:absolute;top:0;width:100%}.menu-icon:hover:after{background:#cacaca;-webkit-box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca;box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca}.menu-icon.dark{cursor:pointer;display:inline-block;height:16px;position:relative;vertical-align:middle;width:20px}.menu-icon.dark:after{background:#0a0a0a;-webkit-box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a;box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a;content:"";display:block;height:2px;left:0;position:absolute;top:0;width:100%}.menu-icon.dark:hover:after{background:#8a8a8a;-webkit-box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a;box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a}.accordion-menu li{width:100%}.accordion-menu .is-accordion-submenu a,.accordion-menu a{padding:.7rem 1rem}.accordion-menu .nested.is-accordion-submenu{margin-left:1rem;margin-right:0}.accordion-menu.align-right .nested.is-accordion-submenu{margin-left:0;margin-right:1rem}.accordion-menu .is-accordion-submenu-parent:not(.has-submenu-toggle)>a{position:relative}.accordion-menu .is-accordion-submenu-parent:not(.has-submenu-toggle)>a:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;content:"";display:block;height:0;margin-top:-3px;position:absolute;right:1rem;top:50%;width:0}.accordion-menu.align-left .is-accordion-submenu-parent>a:after{left:auto;right:1rem}.accordion-menu.align-right .is-accordion-submenu-parent>a:after{left:1rem;right:auto}.accordion-menu .is-accordion-submenu-parent[aria-expanded=true]>a:after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg);-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.is-accordion-submenu-parent{position:relative}.has-submenu-toggle>a{margin-right:40px}.submenu-toggle{cursor:pointer;height:40px;position:absolute;right:0;top:0;width:40px}.submenu-toggle:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;bottom:0;content:"";display:block;height:0;margin:auto;top:0;width:0}.submenu-toggle[aria-expanded=true]:after{-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1);-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.submenu-toggle-text{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.is-drilldown{overflow:hidden;position:relative}.is-drilldown li{display:block}.is-drilldown.animate-height{-webkit-transition:height .5s;transition:height .5s}.drilldown a{background:#fefefe;padding:.7rem 1rem}.drilldown .is-drilldown-submenu{background:#fefefe;left:100%;position:absolute;top:0;-webkit-transition:-webkit-transform .15s linear;transition:-webkit-transform .15s linear;transition:transform .15s linear;transition:transform .15s linear,-webkit-transform .15s linear;width:100%;z-index:-1}.drilldown .is-drilldown-submenu.is-active{display:block;-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);z-index:1}.drilldown .is-drilldown-submenu.is-closing{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%)}.drilldown .is-drilldown-submenu a{padding:.7rem 1rem}.drilldown .nested.is-drilldown-submenu{margin-left:0;margin-right:0}.drilldown .drilldown-submenu-cover-previous{min-height:100%}.drilldown .is-drilldown-submenu-parent>a{position:relative}.drilldown .is-drilldown-submenu-parent>a:after{margin-top:-6px;position:absolute;top:50%}.drilldown .is-drilldown-submenu-parent>a:after,.drilldown.align-left .is-drilldown-submenu-parent>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;right:1rem;width:0}.drilldown.align-left .is-drilldown-submenu-parent>a:after{left:auto}.drilldown.align-right .is-drilldown-submenu-parent>a:after{left:1rem;right:auto}.drilldown .js-drilldown-back>a:before,.drilldown.align-right .is-drilldown-submenu-parent>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;width:0}.drilldown .js-drilldown-back>a:before{display:inline-block;margin-right:.75rem;vertical-align:middle}.dropdown.menu>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu>li.opens-right>.is-dropdown-submenu{left:0;right:auto;top:100%}.dropdown.menu>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu>li.is-dropdown-submenu-parent>a:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;content:"";display:block;height:0;left:auto;margin-top:-3px;right:5px;width:0}[data-whatinput=mouse] .dropdown.menu a{outline:0}.dropdown.menu>li>a{padding:.7rem 1rem}.dropdown.menu>li.is-active>a{background:0 0;color:#1779ba}.no-js .dropdown.menu ul{display:none}.dropdown.menu .nested.is-dropdown-submenu{margin-left:0;margin-right:0}.dropdown.menu.vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%;top:0}.dropdown.menu.vertical>li.opens-right>.is-dropdown-submenu{left:100%;right:auto}.dropdown.menu.vertical>li>a:after{right:14px}.dropdown.menu.vertical>li.opens-left>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;left:5px;right:auto;width:0}.dropdown.menu.vertical>li.opens-right>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;width:0}@media print,screen and (min-width:40em){.dropdown.menu.medium-horizontal>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu.medium-horizontal>li.opens-right>.is-dropdown-submenu{left:0;right:auto;top:100%}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;content:"";display:block;height:0;left:auto;margin-top:-3px;right:5px;width:0}.dropdown.menu.medium-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.medium-vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%;top:0}.dropdown.menu.medium-vertical>li.opens-right>.is-dropdown-submenu{left:100%;right:auto}.dropdown.menu.medium-vertical>li>a:after{right:14px}.dropdown.menu.medium-vertical>li.opens-left>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;left:5px;right:auto;width:0}.dropdown.menu.medium-vertical>li.opens-right>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;width:0}}@media print,screen and (min-width:64em){.dropdown.menu.large-horizontal>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu.large-horizontal>li.opens-right>.is-dropdown-submenu{left:0;right:auto;top:100%}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;content:"";display:block;height:0;left:auto;margin-top:-3px;right:5px;width:0}.dropdown.menu.large-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.large-vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%;top:0}.dropdown.menu.large-vertical>li.opens-right>.is-dropdown-submenu{left:100%;right:auto}.dropdown.menu.large-vertical>li>a:after{right:14px}.dropdown.menu.large-vertical>li.opens-left>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;left:5px;right:auto;width:0}.dropdown.menu.large-vertical>li.opens-right>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;width:0}}.dropdown.menu.align-right .is-dropdown-submenu.first-sub{left:auto;right:0;top:100%}.is-dropdown-menu.vertical{width:100px}.is-dropdown-menu.vertical.align-right{float:right}.is-dropdown-submenu-parent{position:relative}.is-dropdown-submenu-parent a:after{left:auto;margin-top:-6px;position:absolute;right:5px;top:50%}.is-dropdown-submenu-parent.opens-inner>.is-dropdown-submenu{left:auto;top:100%}.is-dropdown-submenu-parent.opens-left>.is-dropdown-submenu{left:auto;right:100%}.is-dropdown-submenu-parent.opens-right>.is-dropdown-submenu{left:100%;right:auto}.is-dropdown-submenu{background:#fefefe;border:1px solid #cacaca;display:none;left:100%;min-width:200px;position:absolute;top:0;z-index:1}.dropdown .is-dropdown-submenu a{padding:.7rem 1rem}.is-dropdown-submenu .is-dropdown-submenu-parent>a:after{right:14px}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-left>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;left:5px;right:auto;width:0}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-right>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;width:0}.is-dropdown-submenu .is-dropdown-submenu{margin-top:-1px}.is-dropdown-submenu>li{width:100%}.is-dropdown-submenu.js-dropdown-active{display:block}.is-off-canvas-open{overflow:hidden}.js-off-canvas-overlay{background:hsla(0,0%,100%,.25);height:100%;left:0;opacity:0;overflow:hidden;position:absolute;top:0;-webkit-transition:opacity .5s ease,visibility .5s ease;transition:opacity .5s ease,visibility .5s ease;visibility:hidden;width:100%;z-index:11}.js-off-canvas-overlay.is-visible{opacity:1;visibility:visible}.js-off-canvas-overlay.is-closable{cursor:pointer}.js-off-canvas-overlay.is-overlay-absolute{position:absolute}.js-off-canvas-overlay.is-overlay-fixed{position:fixed}.off-canvas-wrapper{overflow:hidden;position:relative}.off-canvas{-webkit-backface-visibility:hidden;backface-visibility:hidden;background:#e6e6e6;position:fixed;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:12}[data-whatinput=mouse] .off-canvas{outline:0}.off-canvas.is-transition-push{z-index:12}.off-canvas.is-closed{visibility:hidden}.off-canvas.is-transition-overlap{z-index:13}.off-canvas.is-transition-overlap.is-open{-webkit-box-shadow:0 0 10px hsla(0,0%,4%,.7);box-shadow:0 0 10px hsla(0,0%,4%,.7)}.off-canvas.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-absolute{-webkit-backface-visibility:hidden;backface-visibility:hidden;background:#e6e6e6;position:absolute;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:12}[data-whatinput=mouse] .off-canvas-absolute{outline:0}.off-canvas-absolute.is-transition-push{z-index:12}.off-canvas-absolute.is-closed{visibility:hidden}.off-canvas-absolute.is-transition-overlap{z-index:13}.off-canvas-absolute.is-transition-overlap.is-open{-webkit-box-shadow:0 0 10px hsla(0,0%,4%,.7);box-shadow:0 0 10px hsla(0,0%,4%,.7)}.off-canvas-absolute.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.position-left{-webkit-overflow-scrolling:touch;height:100%;left:0;overflow-y:auto;top:0;width:250px}.off-canvas-content .off-canvas.position-left,.position-left{-webkit-transform:translateX(-250px);-ms-transform:translateX(-250px);transform:translateX(-250px)}.off-canvas-content .off-canvas.position-left.is-transition-overlap.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-content.is-open-left.has-transition-push{-webkit-transform:translateX(250px);-ms-transform:translateX(250px);transform:translateX(250px)}.position-left.is-transition-push{-webkit-box-shadow:inset -13px 0 20px -13px hsla(0,0%,4%,.25);box-shadow:inset -13px 0 20px -13px hsla(0,0%,4%,.25)}.position-right{-webkit-overflow-scrolling:touch;height:100%;overflow-y:auto;right:0;top:0;width:250px}.off-canvas-content .off-canvas.position-right,.position-right{-webkit-transform:translateX(250px);-ms-transform:translateX(250px);transform:translateX(250px)}.off-canvas-content .off-canvas.position-right.is-transition-overlap.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-content.is-open-right.has-transition-push{-webkit-transform:translateX(-250px);-ms-transform:translateX(-250px);transform:translateX(-250px)}.position-right.is-transition-push{-webkit-box-shadow:inset 13px 0 20px -13px hsla(0,0%,4%,.25);box-shadow:inset 13px 0 20px -13px hsla(0,0%,4%,.25)}.position-top{-webkit-overflow-scrolling:touch;height:250px;left:0;overflow-x:auto;top:0;width:100%}.off-canvas-content .off-canvas.position-top,.position-top{-webkit-transform:translateY(-250px);-ms-transform:translateY(-250px);transform:translateY(-250px)}.off-canvas-content .off-canvas.position-top.is-transition-overlap.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-content.is-open-top.has-transition-push{-webkit-transform:translateY(250px);-ms-transform:translateY(250px);transform:translateY(250px)}.position-top.is-transition-push{-webkit-box-shadow:inset 0 -13px 20px -13px hsla(0,0%,4%,.25);box-shadow:inset 0 -13px 20px -13px hsla(0,0%,4%,.25)}.position-bottom{-webkit-overflow-scrolling:touch;bottom:0;height:250px;left:0;overflow-x:auto;width:100%}.off-canvas-content .off-canvas.position-bottom,.position-bottom{-webkit-transform:translateY(250px);-ms-transform:translateY(250px);transform:translateY(250px)}.off-canvas-content .off-canvas.position-bottom.is-transition-overlap.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-content.is-open-bottom.has-transition-push{-webkit-transform:translateY(-250px);-ms-transform:translateY(-250px);transform:translateY(-250px)}.position-bottom.is-transition-push{-webkit-box-shadow:inset 0 13px 20px -13px hsla(0,0%,4%,.25);box-shadow:inset 0 13px 20px -13px hsla(0,0%,4%,.25)}.off-canvas-content{-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-transition-overlap,.off-canvas-content.has-transition-push{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.off-canvas-content .off-canvas.is-open,.off-canvas-content.has-transition-push{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}@media print,screen and (min-width:40em){.position-left.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-left.reveal-for-medium .close-button{display:none}.off-canvas-content .position-left.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-left,.position-left.reveal-for-medium~.off-canvas-content{margin-left:250px}.position-right.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-right.reveal-for-medium .close-button{display:none}.off-canvas-content .position-right.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-right,.position-right.reveal-for-medium~.off-canvas-content{margin-right:250px}.position-top.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-top.reveal-for-medium .close-button{display:none}.off-canvas-content .position-top.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-top,.position-top.reveal-for-medium~.off-canvas-content{margin-top:250px}.position-bottom.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-bottom.reveal-for-medium .close-button{display:none}.off-canvas-content .position-bottom.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-bottom,.position-bottom.reveal-for-medium~.off-canvas-content{margin-bottom:250px}}@media print,screen and (min-width:64em){.position-left.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-left.reveal-for-large .close-button{display:none}.off-canvas-content .position-left.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-left,.position-left.reveal-for-large~.off-canvas-content{margin-left:250px}.position-right.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-right.reveal-for-large .close-button{display:none}.off-canvas-content .position-right.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-right,.position-right.reveal-for-large~.off-canvas-content{margin-right:250px}.position-top.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-top.reveal-for-large .close-button{display:none}.off-canvas-content .position-top.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-top,.position-top.reveal-for-large~.off-canvas-content{margin-top:250px}.position-bottom.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-bottom.reveal-for-large .close-button{display:none}.off-canvas-content .position-bottom.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-bottom,.position-bottom.reveal-for-large~.off-canvas-content{margin-bottom:250px}}@media print,screen and (min-width:40em){.off-canvas.in-canvas-for-medium{background:0 0;height:auto;overflow:visible;position:static;-webkit-transition:none;transition:none;visibility:visible;width:auto}.off-canvas.in-canvas-for-medium.position-bottom,.off-canvas.in-canvas-for-medium.position-left,.off-canvas.in-canvas-for-medium.position-right,.off-canvas.in-canvas-for-medium.position-top{-webkit-box-shadow:none;box-shadow:none;-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas.in-canvas-for-medium .close-button{display:none}}@media print,screen and (min-width:64em){.off-canvas.in-canvas-for-large{background:0 0;height:auto;overflow:visible;position:static;-webkit-transition:none;transition:none;visibility:visible;width:auto}.off-canvas.in-canvas-for-large.position-bottom,.off-canvas.in-canvas-for-large.position-left,.off-canvas.in-canvas-for-large.position-right,.off-canvas.in-canvas-for-large.position-top{-webkit-box-shadow:none;box-shadow:none;-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas.in-canvas-for-large .close-button{display:none}}html.is-reveal-open{overflow-y:hidden;position:fixed;width:100%}html.is-reveal-open.zf-has-scroll{-webkit-overflow-scrolling:touch;overflow-y:scroll}html.is-reveal-open body{overflow-y:hidden}.reveal-overlay{background-color:hsla(0,0%,4%,.45);bottom:0;left:0;position:fixed;right:0;top:0;z-index:1005}.reveal,.reveal-overlay{-webkit-overflow-scrolling:touch;display:none;overflow-y:auto}.reveal{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:#fefefe;border:1px solid #cacaca;border-radius:0;margin-left:auto;margin-right:auto;padding:1rem;position:relative;top:100px;z-index:1006}[data-whatinput=mouse] .reveal{outline:0}@media print,screen and (min-width:40em){.reveal{min-height:0}}.reveal .column{min-width:0}.reveal>:last-child{margin-bottom:0}@media print,screen and (min-width:40em){.reveal{max-width:75rem;width:600px}}.reveal.collapse{padding:0}@media print,screen and (min-width:40em){.reveal.tiny{max-width:75rem;width:30%}.reveal.small{max-width:75rem;width:50%}.reveal.large{max-width:75rem;width:90%}}.reveal.full{border:0;border-radius:0;bottom:0;height:100%;left:0;margin-left:0;max-width:none;min-height:100%;right:0;top:0;width:100%}@media print,screen and (max-width:39.99875em){.reveal{border:0;border-radius:0;bottom:0;height:100%;left:0;margin-left:0;max-width:none;min-height:100%;right:0;top:0;width:100%}}.reveal.without-overlay{position:fixed}.sticky,.sticky-container{position:relative}.sticky{-webkit-transform:translateZ(0);transform:translateZ(0);z-index:0}.sticky.is-stuck{position:fixed;width:100%;z-index:5}.sticky.is-stuck.is-at-top{top:0}.sticky.is-stuck.is-at-bottom{bottom:0}.sticky.is-anchored{left:auto;position:relative;right:auto}.sticky.is-anchored.is-at-bottom{bottom:0}.title-bar{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;background:#0a0a0a;color:#fefefe;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:flex-start;justify-content:flex-start;padding:.5rem}.title-bar .menu-icon{margin-left:.25rem;margin-right:.25rem}.title-bar-left,.title-bar-right{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}.title-bar-right{text-align:right}.title-bar-title{display:inline-block;font-weight:700;vertical-align:middle}.top-bar{-webkit-box-pack:justify;-ms-flex-pack:justify;-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:space-between;justify-content:space-between;padding:.5rem}.top-bar,.top-bar ul{background-color:#e6e6e6}.top-bar input{margin-right:1rem;max-width:200px}.top-bar .input-group-field{margin-right:0;width:100%}.top-bar input.button{width:auto}.top-bar .top-bar-left,.top-bar .top-bar-right{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}@media print,screen and (min-width:40em){.top-bar{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.top-bar .top-bar-left{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;margin-right:auto}.top-bar .top-bar-right{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;margin-left:auto}}@media print,screen and (max-width:63.99875em){.top-bar.stacked-for-medium{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.top-bar.stacked-for-medium .top-bar-left,.top-bar.stacked-for-medium .top-bar-right{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}@media print,screen and (max-width:74.99875em){.top-bar.stacked-for-large{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.top-bar.stacked-for-large .top-bar-left,.top-bar.stacked-for-large .top-bar-right{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}.top-bar-title{margin:.5rem 1rem .5rem 0}.top-bar-left,.top-bar-right,.top-bar-title{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.float-left{float:left!important}.float-right{float:right!important}.float-center{display:block;margin-left:auto;margin-right:auto}.clearfix:after,.clearfix:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.clearfix:after{clear:both}.align-left{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.align-right{-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end}.align-center{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center}.align-justify{-webkit-box-pack:justify;-ms-flex-pack:justify;-webkit-justify-content:space-between;justify-content:space-between}.align-spaced{-ms-flex-pack:distribute;-webkit-justify-content:space-around;justify-content:space-around}.align-left.vertical.menu>li>a{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.align-right.vertical.menu>li>a{-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end}.align-center.vertical.menu>li>a{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center}.align-top{-webkit-box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;align-items:flex-start}.align-self-top{-ms-flex-item-align:start;-webkit-align-self:flex-start;align-self:flex-start}.align-bottom{-webkit-box-align:end;-ms-flex-align:end;-webkit-align-items:flex-end;align-items:flex-end}.align-self-bottom{-ms-flex-item-align:end;-webkit-align-self:flex-end;align-self:flex-end}.align-middle{-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center}.align-self-middle{-ms-flex-item-align:center;-webkit-align-self:center;align-self:center}.align-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch}.align-self-stretch{-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch}.align-center-middle{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-box-align:center;-ms-flex-align:center;-ms-flex-line-pack:center;-webkit-align-content:center;align-content:center;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.small-order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;-webkit-order:1;order:1}.small-order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;-webkit-order:2;order:2}.small-order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;-webkit-order:3;order:3}.small-order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;-webkit-order:4;order:4}.small-order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;-webkit-order:5;order:5}.small-order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;-webkit-order:6;order:6}@media print,screen and (min-width:40em){.medium-order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;-webkit-order:1;order:1}.medium-order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;-webkit-order:2;order:2}.medium-order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;-webkit-order:3;order:3}.medium-order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;-webkit-order:4;order:4}.medium-order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;-webkit-order:5;order:5}.medium-order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;-webkit-order:6;order:6}}@media print,screen and (min-width:64em){.large-order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;-webkit-order:1;order:1}.large-order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;-webkit-order:2;order:2}.large-order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;-webkit-order:3;order:3}.large-order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;-webkit-order:4;order:4}.large-order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;-webkit-order:5;order:5}.large-order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;-webkit-order:6;order:6}}.flex-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flex-child-auto{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.flex-child-grow{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto}.flex-child-shrink{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.flex-dir-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.flex-dir-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flex-dir-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.flex-dir-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}@media print,screen and (min-width:40em){.medium-flex-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.medium-flex-child-auto{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.medium-flex-child-grow{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto}.medium-flex-child-shrink{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.medium-flex-dir-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.medium-flex-dir-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.medium-flex-dir-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.medium-flex-dir-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}}@media print,screen and (min-width:64em){.large-flex-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.large-flex-child-auto{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.large-flex-child-grow{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto}.large-flex-child-shrink{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.large-flex-dir-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.large-flex-dir-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.large-flex-dir-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.large-flex-dir-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}}.hide{display:none!important}.invisible{visibility:hidden}.visible{visibility:visible}@media print,screen and (max-width:39.99875em){.hide-for-small-only{display:none!important}}@media screen and (max-width:0em),screen and (min-width:40em){.show-for-small-only{display:none!important}}@media print,screen and (min-width:40em){.hide-for-medium{display:none!important}}@media screen and (max-width:39.99875em){.show-for-medium{display:none!important}}@media print,screen and (min-width:40em)and (max-width:63.99875em){.hide-for-medium-only{display:none!important}}@media screen and (max-width:39.99875em),screen and (min-width:64em){.show-for-medium-only{display:none!important}}@media print,screen and (min-width:64em){.hide-for-large{display:none!important}}@media screen and (max-width:63.99875em){.show-for-large{display:none!important}}@media print,screen and (min-width:64em)and (max-width:74.99875em){.hide-for-large-only{display:none!important}}@media screen and (max-width:63.99875em),screen and (min-width:75em){.show-for-large-only{display:none!important}}.show-for-sr,.show-on-focus{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.show-on-focus:active,.show-on-focus:focus{clip:auto!important;height:auto!important;overflow:visible!important;position:static!important;white-space:normal!important;width:auto!important}.hide-for-portrait,.show-for-landscape{display:block!important}@media screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:block!important}}@media screen and (orientation:portrait){.hide-for-portrait,.show-for-landscape{display:none!important}}.hide-for-landscape,.show-for-portrait{display:none!important}@media screen and (orientation:landscape){.hide-for-landscape,.show-for-portrait{display:none!important}}@media screen and (orientation:portrait){.hide-for-landscape,.show-for-portrait{display:block!important}}.show-for-dark-mode{display:none}.hide-for-dark-mode{display:block}@media screen and (prefers-color-scheme:dark){.show-for-dark-mode{display:block!important}.hide-for-dark-mode{display:none!important}}.show-for-ie{display:none}@media (-ms-high-contrast:active),(-ms-high-contrast:none){.show-for-ie{display:block!important}.hide-for-ie{display:none!important}}.show-for-sticky{display:none}.is-stuck .show-for-sticky{display:block}.is-stuck .hide-for-sticky{display:none}@font-face{font-display:"swap";font-family:FontAwesome}html{box-sizing:border-box;scroll-padding-top:100px}body{font-family:Roboto,sans-serif;font-size:16px;line-height:1}*,:after,:before{box-sizing:inherit}a{color:#3c4fe0}a.reference:after{font-family:FontAwesome;font-size:12px;padding:0 4px}a.reference.external:after{content:""}a.reference.download:after{content:""}a:hover{color:#3c4fe0;font-weight:500}.headerlink{margin-left:5px;visibility:hidden}.toc-backref:hover{color:#23263b}h1,h2,h3,h4,h5,h6{font-family:Roboto,sans-serif;font-size:16px;font-weight:500;letter-spacing:.2px;line-height:24px;margin-bottom:16px}h1:hover>a.headerlink,h2:hover>a.headerlink,h3:hover>a.headerlink,h4:hover>a.headerlink,h5:hover>a.headerlink,h6:hover>a.headerlink{visibility:visible}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color:inherit}h1{font-size:32px;font-weight:700;line-height:40px;margin-bottom:28px}h2{font-size:24px;line-height:32px}h3{font-size:20px}h4{font-size:18px}h5{font-size:16px}h6{font-weight:400}img{max-width:100%}button:focus{outline:0}blockquote{border:0;margin:0;padding:0}blockquote,blockquote p,cite{color:inherit}cite{display:inline;font-size:inherit}cite:before{content:""}.show{display:block!important}.centered{display:block;margin:0 auto}.break{flex-basis:100%;height:0}@media screen and (min-width:1024px){h1{font-size:36px}}.admonition-title:before,.contents.local>ul>li a:before,.scylla-icon,.secondary-side-nav__content li a:before{background-repeat:no-repeat;background-size:contain;display:inline-block;filter:brightness(0);vertical-align:middle}.scylla-icon--about-team{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1taXRlcmxpbWl0OjEwfS5jbHMtMntzdHJva2UtbGluZWNhcDpyb3VuZH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik00LjY2IDkuODEgMi42MyAxMWEyLjA4IDIuMDggMCAwIDAtMS4xMyAxLjgzdjcuODFjLjE5IDEuMTEuNSAxLjUzIDEuNSAxLjQ3TTcuMDYgOS45NGwxLjQ0Ljk0IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMy41IDE4LjV2NS4zNE05LjUgMTguNXY1LjM0TTguNTQgMTguNDJ2NS4zM00xNS41IDE4LjV2NS4zNE0xNi41IDE4LjV2NS4zNE0zLjMzIDIwLjUzaDUuMDhNMTEuNDUgOC44NGwuMDYuMDZhMS42NSAxLjY1IDAgMCAwIDIuMzQgMGgwIiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMTIuNDIgNy41YTEuODEgMS44MSAwIDAgMS0xLjkyLTEuNzdWNWExLjk0IDEuOTQgMCAwIDEgMS45Mi0yIDIuMDcgMi4wNyAwIDAgMSAyLjA4IDJ2Ljc3YTIgMiAwIDAgMS0yLjA4IDEuNzNaTTExLjQyIDguNzQgOS42MyA5LjlhMi4wNyAyLjA3IDAgMCAwLTEuMTMgMS44NXY3LjgyQTEuNDcgMS40NyAwIDAgMCAxMCAyMU0xMy43NSA5LjE4bDIgLjY1Yy43LjM1Ljc2IDEuMDYuNzYgMS44NHY3LjljMCAuNzctLjIzIDEuMjQtMSAxLjI0IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNOS45MyAxOS41aDUuNCIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTE5LjQyIDkuMTJhMi4wNyAyLjA3IDAgMCAwIDIuMDgtMS45M3YtLjc3YTIuMDcgMi4wNyAwIDAgMC0yLjA4LTEuOTIgMS45MyAxLjkzIDAgMCAwLTEuOTIgMS45MnYuNzdhMS45NCAxLjk0IDAgMCAwIDEuOTIgMS45M1pNNS41OSA5LjEyYTEuOTMgMS45MyAwIDAgMCAxLjkyLTEuOTN2LS43N0ExLjkzIDEuOTMgMCAwIDAgNS41OSA0LjUgMi4wOCAyLjA4IDAgMCAwIDMuNSA2LjQydi43N2EyLjA4IDIuMDggMCAwIDAgMi4wOSAxLjkzWk0yMC40NCA5LjgxbDIgMS4xN2EyLjA2IDIuMDYgMCAwIDEgMS4xMyAxLjg1djcuODFjLS4xOCAxLjExLS40NyAxLjUzLTEuNDcgMS40N00xOC4wNCA5Ljk0bC0xLjQ0LjkzIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMjEuNiAxOC41djUuMzRNMjEuNzcgMjAuNTNoLTUuMDgiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.scylla-icon--about-us{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8zIiB2aWV3Qm94PSIwIDAgMjAgMjAiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6LjhweH08L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNi4yOCAxOS40OGMtLjEyLjA4LS4wOC4wNy0uMjMuMS0uNTguMDktMS4xMi0uMjgtMS4yNS0uODQgMCAwLTIuMy05LjE4LTIuMy0xMS4xMUMyLjUgMy42IDUuODguNDQgMTAuMzguNDRTMTcuNSAzLjQ4IDE3LjUgNy41YzAgMS45My0xLjMyIDExLjIzLTEuMzIgMTEuMjMtLjEzLjU2LS42Ny45NC0xLjI1Ljg0LS4xMi0uMDItLjEzIDAtLjIzLS4wNyIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTE1Ljc1IDE1Ljc1Yy0uMTcgMS4xNS0uMjIgMi4zNC0uNTUgMy40Ni0uMzcuODUtMS42MyAxLjA2LTIuMjIuMzMtLjI1LS4yOC4xOS0uNjguNDQtLjQuNDMuNDYgMS4yNC4xOCAxLjMxLS40NGwuMDYtLjM0Yy4xOS0uODkuMzUtMS43OS41Ny0yLjY4LjA1LS4yNC40Mi0uMTcuMzkuMDdaIi8+PHBhdGggZD0iTTExLjUgN2MwIDEuOS0xLjU2IDMuNS0zLjQ2IDMuNVM0LjUgOC45IDQuNSA3czEuNjQtMy41IDMuNTQtMy41UzExLjUgNS4xIDExLjUgN1oiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik04LjU1IDQuNzVjLS41OS4xMi0uNzEgMS40Mi0uMzYgMS43OC4yMy4yMy43MS4zMS43MS40N3MtLjQ4LjI0LS43MS40N2MtLjM2LjM2LS4yNCAxLjY2LjM2IDEuNzguNzEuMTQgMS43OC0uNzEgMS43OC0yLjI1UzkuMjYgNC42MSA4LjU1IDQuNzVaTTYuNTEgMTIuMmMyLjEyLjMxIDQuMzQtLjIgNS42OC0xLjk2LjMyLS40MS45Ni4xMS42Mi41MS0uNzYuOS0xLjc4IDEuNjMtMi45MyAxLjk1LTEuMTQuMzMtMi4zMy4zMS0zLjQ2LjE2YS4zNC4zNCAwIDAgMS0uMjktLjM4Yy4wMi0uMTguMTktLjMxLjM3LS4yOVpNNy45NyAxOS41OWMtLjk5Ljk2LTIuMzYuMDgtMi4zNi0xLjE1LS4xMi0uOS0uMjctMS43OS0uMzctMi42OS0uMDEtLjExLjA3LS4yMS4xOC0uMjIuMS0uMDEuMTkuMDYuMjEuMTUuMjIuODguMzggMS43Ny41NiAyLjY2LjAxLjc4LjY4IDEuMzggMS4zNS44My4yNy0uMjcuNjkuMTYuNDIuNDNaIi8+PHBhdGggZD0iTTkuNzUgMTkuMjdjLS40Mi45LTEuOC45Ni0yLjMyLjExLS41LTEuMTMtLjMxLTIuNS0uNDctMy43MiAwLS4xMS4wOC0uMi4xOS0uMjEuMSAwIC4xOS4wNy4yMS4xNy4xNy45NS4yOCAxLjkxLjQyIDIuODcuMDEuNDUuMjMuNzQuNTcuODUuMzMuMS43MS0uMDUuODgtLjM2LjE4LS4zNC43MS0uMDUuNTIuMjlaTTE0LjAzIDE1LjY2Yy0uMTYgMS4yMy4wMyAyLjU3LS40NiAzLjcyLS41Mi44Ni0xLjkxLjc5LTIuMzItLjExLS4xNy0uMzQuMzUtLjYxLjUzLS4yOC40Mi43MSAxLjQ4LjM4IDEuNDUtLjQ5LjE0LS45Ni4yNS0xLjkyLjQyLTIuODcuMDQtLjI0LjQxLS4yLjQuMDRaIi8+PHBhdGggZD0iTTExLjg1IDE1LjU0Yy4wMi43OS4wMSAxLjU4LjAxIDIuMzctLjAyLjQxLjA3LjktLjE0IDEuMjktLjQzIDEuMDItMi4wMSAxLjAyLTIuNDUgMC0uMjEtLjM5LS4xMy0uODktLjE0LTEuMjkgMC0uNzkgMC0xLjU4LjAxLTIuMzcgMC0uMTEuMS0uMi4yMS0uMTkuMSAwIC4xOC4wOC4xOS4xOC4wNy43OS4xIDEuNTguMTUgMi4zNy4wMy4yNyAwIC44Mi4xMyAxLjA0LjEzLjI2LjQuNDMuNjguNDIuNDYgMCAuNzktLjQuNzctLjg3bC4wMy0uNTljLjA0LS43OS4wOC0xLjU4LjE1LTIuMzcuMDItLjI0LjQtLjIzLjQuMDFaIi8+PC9zdmc+)}.scylla-icon--about-us-m{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNi4zOCAzMi40MyI+PHBhdGggZD0iTTYuNTUgMzEuNjRjLS4yLjEzLS40My4yMi0uNjkuMjZhMS44MSAxLjgxIDAgMCAxLTIuMDYtMS4zOVMuNDkgMTQuOTkuNDkgMTEuODJDLjUgNS4xOSA1Ljc3LjUgMTMuMTkuNXMxMi42OSA0LjY5IDEyLjY5IDExLjMyYzAgMy4xOC0zLjMxIDE4LjY5LTMuMzEgMTguNjlhMS44MSAxLjgxIDAgMCAxLTIuNjIgMS4yIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZCIvPjxwYXRoIGQ9Ik0yMS44NiAyNS4zNmMtLjI4IDEuOS0uMzcgMy44Ni0uOTEgNS43MS0uNjEgMS40MS0yLjY4IDEuNzUtMy42Ni41NS0uNDEtLjQ3LjMxLTEuMTEuNzMtLjY2LjcxLjc2IDIuMDQuMjkgMi4xNi0uNzMuMzItMS42Ni42NS0zLjMzIDEuMDQtNC45OC4wOS0uMzkuNy0uMjguNjUuMTFaIi8+PHBhdGggZD0iTTE0LjggMTAuNTdjMCAzLjEzLTIuNTMgNS42Ni01LjY2IDUuNjZzLTUuNDctMi41My01LjQ3LTUuNjYgMi4zNC01LjY2IDUuNDctNS42NiA1LjY2IDIuNTMgNS42NiA1LjY2WiIgc3R5bGU9InN0cm9rZS13aWR0aDouOXB4O2ZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQiLz48cGF0aCBkPSJNMTAuMzEgNi44NmMtLjk4LjItMS4xNyAyLjM0LS41OSAyLjkzLjM4LjM4IDEuMTcuNTEgMS4xNy43OHMtLjc5LjQtMS4xNy43OGMtLjU5LjU5LS4zOSAyLjczLjU5IDIuOTMgMS4xNi4yMyAyLjkzLTEuMTcgMi45My0zLjcxcy0xLjc2LTMuOTQtMi45My0zLjcxWk02LjgyIDE4LjUxYzMuNDkuODkgNi45Ny0uNSA5LjUxLTIuOTMuNDctLjQ0IDEuMTYuMzEuNjguNzQtMS4zOCAxLjIzLTIuOTggMi4yOS00Ljc5IDIuODctMS44LjU5LTMuNzcuNTgtNS41OC4xNGEuNDIxLjQyMSAwIDAgMS0uMzEtLjVjLjA1LS4yMi4yOC0uMzYuNS0uMzFaIi8+PHBhdGggZD0iTTE2LjczIDE2LjY3Yy0uMTItLjQ2LS41MS0uODMtLjk5LS44My0uNzUtLjAyLS41OS0xLjE3LjE0LS45OS44MS4xNiAxLjQzLjg1IDEuNSAxLjY2LjA4LjQtLjU0LjU0LS42NS4xNVpNOS4wMyAzMS43Yy0xLjI2IDEuMzYtMy42Mi40NS0zLjgtMS4zNWwtLjA5LS41NWMtLjIxLTEuNDgtLjQ1LTIuOTUtLjYtNC40NC0uMDItLjE4LjExLS4zNC4yOS0uMzYuMTctLjAyLjMyLjA5LjM1LjI1LjM5IDEuNjMuNzEgMy4yOCAxLjAzIDQuOTMuMDkgMS4wMiAxLjM4IDEuNTQgMi4xMi44MS40NS0uNDQgMS4xNC4yNi42OS43WiIvPjxwYXRoIGQ9Ik0xMS45NiAzMS4xNmMtMSAxLjk4LTQuMDQgMS4zLTQuMjEtLjg4LS4xNS0xLjY5LS4zLTMuMzgtLjM5LTUuMDcgMC0uMTguMTMtLjM0LjMxLS4zNC4xNyAwIC4zMS4xMS4zNC4yNy4yOCAxLjY3LjUgMy4zNS43MiA1LjAzLjA5IDEuMiAxLjc3IDEuNTkgMi4zNi41MS4zMS0uNTYgMS4xNi0uMDkuODcuNDdaTTE5LjAzIDI1LjIxYy0uMDggMS42OS0uMjQgMy4zOC0uMzkgNS4wNy0uMDQuMzctLjE3Ljc1LS4zOCAxLjA2LS44NiAxLjQtMy4xMSAxLjMxLTMuODMtLjE3LS4zLS41Ni41NS0xLjAzLjg2LS40OC41OSAxLjA4IDIuMjcuNjkgMi4zNS0uNTIuMjItMS42OC40My0zLjM2LjcyLTUuMDMuMDYtLjQuNjgtLjMzLjY1LjA3WiIvPjxwYXRoIGQ9Ik0xNS40MyAyNS4wMmMuMDQgMS4zMS4wMiAyLjYxLjAyIDMuOTEtLjAzLjY3LjExIDEuNDgtLjIzIDIuMTMtLjc0IDEuNjktMy4yOSAxLjY5LTQuMDMgMC0uMzQtLjY1LS4yMS0xLjQ3LS4yNC0yLjEzIDAtMS4zLS4wMi0yLjYxLjAyLTMuOTEgMC0uMTguMTYtLjMyLjM0LS4zMi4xNyAwIC4zLjE0LjMyLjMuMTEgMS4zLjE3IDIuNi4yNCAzLjkxLjA1LjQ1IDAgMS4zNS4yMSAxLjcyLjIxLjQzLjY2LjcxIDEuMTIuNy40Ni4wMi45MS0uMjcgMS4xMi0uNjkuMjItLjM2LjE2LTEuMjguMjEtMS43Mi4wNy0xLjMuMTMtMi42MS4yNC0zLjkxLjAyLS40LjY2LS4zOC42Ni4wMloiLz48L3N2Zz4=)}.scylla-icon--alternator{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8zIiB2aWV3Qm94PSIwIDAgMjAgMjAiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH08L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNMTcuNSAyLjkxYzAgMS4yOC0zLjY3IDIuNTktOCAyLjU5cy04LTEuMzEtOC0yLjU5UzUuMDkuNSA5LjQyLjVzOC4wOCAxLjEzIDguMDggMi40MVpNMTcuNSA3LjY2YzAgMS4yOC0zLjYzIDIuOC03Ljk2IDIuOFMxLjUgOC45MyAxLjUgNy42Nk0xNy41IDEyLjQ3YzAgMS4yOC0zLjY3IDMuMDMtOCAzLjAzcy04LTEuNzUtOC0zLjAzTTE3LjUgMTcuMjljMCAxLjI4LTMuNzUgMi4zLTguMDggMi4zcy03LjkyLTEuMDMtNy45Mi0yLjNNMS41IDE3LjE5VjIuOTFNMTcuNSAxNy4xOVYyLjkxIiBjbGFzcz0iY2xzLTEiLz48L3N2Zz4=)}.scylla-icon--apps{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTS41IDEuNWgyMHYxNEguNXpNNy41IDE1Ljc0djIuODlNMTIuODMgMTUuNjN2Mi4zMk01LjUgMTguNWg5LjE0IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtMy42NCA1LjU2IDQuNTggMi45MS00LjU4IDIuOTJNOS4xIDEyLjA4aDQuMzIiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--architecture{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTIsLmNscy01e2ZpbGw6bm9uZTtzdHJva2U6Z3JheX0uY2xzLTF7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfS5jbHMtMiwuY2xzLTV7c3Ryb2tlLW1pdGVybGltaXQ6MTB9LmNscy0ye3N0cm9rZS13aWR0aDouOThweH0uY2xzLTV7c3Ryb2tlLXdpZHRoOi45OXB4fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfMiIgZGF0YS1uYW1lPSJDYWxxdWUgMiI+PHBhdGggZD0iTTEuOSAxMC4yN2ExMC44MyAxMC44MyAwIDAgMSA4LjczLTguMzhNMTAuNTEgMjMuMDhBMTAuNzkgMTAuNzkgMCAwIDEgMS43NyAxNE0yMy4yMyAxNGExMC44MSAxMC44MSAwIDAgMS05IDkuMTFNMTQuMjcgMS44OGExMC44MSAxMC44MSAwIDAgMSA4LjgzIDguMzciIGNsYXNzPSJjbHMtMSIvPjxjaXJjbGUgY3g9IjEyLjI1IiBjeT0iMS43NSIgcj0iMS43NSIgY2xhc3M9ImNscy0yIi8+PGNpcmNsZSBjeD0iMTIuMjUiIGN5PSIyMi43NSIgcj0iMS43NSIgY2xhc3M9ImNscy0yIi8+PGNpcmNsZSBjeD0iNC45MiIgY3k9IjQuNzUiIHI9IjEuNzUiIHN0eWxlPSJzdHJva2Utd2lkdGg6Ljk5cHg7ZmlsbDpncmF5O3N0cm9rZS1taXRlcmxpbWl0OjEwO3N0cm9rZTpncmF5Ii8+PGNpcmNsZSBjeD0iMjAuMDkiIGN5PSIxOS45MSIgcj0iMS43NSIgc3R5bGU9InN0cm9rZS13aWR0aDouOTlweDtmaWxsOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlOmdyYXkiLz48Y2lyY2xlIGN4PSIxLjc1IiBjeT0iMTIuMjUiIHI9IjEuNzUiIGNsYXNzPSJjbHMtNSIvPjxjaXJjbGUgY3g9IjIzLjI1IiBjeT0iMTIuMjUiIHI9IjEuNzUiIGNsYXNzPSJjbHMtNSIvPjxjaXJjbGUgY3g9IjQuNzUiIGN5PSIxOS42NCIgcj0iMS43NSIgc3R5bGU9InN0cm9rZS13aWR0aDouOTlweDtmaWxsOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlOmdyYXkiLz48Y2lyY2xlIGN4PSIxOS45MSIgY3k9IjQuNDgiIHI9IjEuNzUiIHN0eWxlPSJzdHJva2Utd2lkdGg6Ljk5cHg7ZmlsbDpncmF5O3N0cm9rZS1taXRlcmxpbWl0OjEwO3N0cm9rZTpncmF5Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--benchmarks{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDozcHh9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV8yIiBkYXRhLW5hbWU9IkNhbHF1ZSAyIj48cGF0aCBkPSJNNS41MSAyNC45MXYtNS44NU0xMi41NyAyNC45MXYtOS43NE0xOS42MiAyNC45MVYxMC4xNSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibS45MSAxNC45OCA1LjEzLTcuOTQgNi4yNSA1Ljg4TDI0IDEiIHN0eWxlPSJzdHJva2UtbGluZWNhcDpyb3VuZDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVqb2luOnJvdW5kIi8+PHBhdGggZD0ibTI1IDUtNS01aDV2NXoiIHN0eWxlPSJmaWxsOmdyYXkiLz48L2c+PC9zdmc+)}.scylla-icon--blog{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibTkgMTUtMi41LTEuNSA4LTEyTDE3IDMgOSAxNXoiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Im02LjUgMTMuNS0uNSAzTDkgMTVsLTIuNS0xLjV6IiBzdHlsZT0iZmlsbDpncmF5O3N0cm9rZTpncmF5O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZCIvPjxwYXRoIGQ9Ik0xOS4yNSAyLjVoNC4yNXYxNmgtMTN2NC4xN0w2LjQ2IDE4LjVsLTQuOTYtLjA0VjIuNWg4LjMxTTE0LjUgMi41bDEuNjcgMS4zMyIgY2xhc3M9ImNscy0xIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--careers{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTEuNSAxMS41NXY4YzAgLjU2IDEuMDcgMiAyIDJoMThjLjg5IDAgMi0xLjQ0IDItMnYtOCIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTIzLjMxIDMuNUgxLjgxYy0uNDggMC0xLjMxLjU1LTEuMzEgMXY2bDEwIDJhOC40NSA4LjQ1IDAgMCAwIDQgMGwxMC0ydi02YzAtLjQ1LS43Mi0xLTEuMTktMVpNMTUuNjIgMy41di0xYzAtLjc2LS42MS0xLTEuMzgtMWgtMy40NWMtLjc2IDAtMS4zOC4yNC0xLjM4IDF2MSIgY2xhc3M9ImNscy0xIi8+PHJlY3Qgd2lkdGg9IjUiIGhlaWdodD0iMy45OSIgeD0iMTAiIHk9IjExIiByeD0iLjU1IiByeT0iLjU1IiBzdHlsZT0iZmlsbDpncmF5Ii8+PC9zdmc+)}.scylla-icon--chevron-left{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTguMDkyIDE2IDEwIDE0LjExMyAzLjgxNyA4IDEwIDEuODg3IDguMDkyIDAgMCA4bDguMDkyIDhaIi8+PC9zdmc+)}.contents.local>ul>li a:before,.scylla-icon--chevron-right,.secondary-side-nav__content li a:before{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTEuOTA4IDAgMCAxLjg4NyA2LjE4MyA4IDAgMTQuMTEzIDEuOTA4IDE2IDEwIDggMS45MDggMFoiLz48L3N2Zz4=)}.scylla-icon--circe{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOCAzMCI+PGRlZnM+PHN0eWxlPi5jbHMtMiwuY2xzLTN7ZmlsbDpub25lO3N0cm9rZTojNGQ0ZDRkO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH0uY2xzLTN7c3Ryb2tlLXdpZHRoOjEuMTFweH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik0yMi4xIDEyaC02LjE2YTEuMDYgMS4wNiAwIDAgMS0uOTQtMS4wNy45My45MyAwIDAgMSAuOTQtLjkzaDYuMTZhLjkzLjkzIDAgMCAxIC45NC45M0ExLjA2IDEuMDYgMCAwIDEgMjIuMSAxMloiIHN0eWxlPSJmaWxsOiM0ZDRkNGQiLz48cGF0aCBkPSJNMTMuNDQgNC40OUg5LjUxdjI0aDE5di0yNEgyNC41IiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMTMgMy40OUg4LjVsLS4wOCAyNi4xSDI5LjVWMy4zOUgyNSIgY2xhc3M9ImNscy0zIi8+PHBhdGggZD0iTTEyLjUgMTguMzhoMTNNMTIuNSAxNS40OWgxM00xMi41IDIxLjQzaDEzTTEyLjUgMjQuNDdoMTNNMTMuNSAyLjVoMTF2My45OGgtMTF6IiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMjEuNS41aC01LjA0djEuOTVsNS4wNC4wNXYtMnoiIGNsYXNzPSJjbHMtMyIvPjwvZz48L3N2Zz4=)}.scylla-icon--clock{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PGNpcmNsZSBjeD0iMTAuNSIgY3k9IjkuNSIgcj0iOSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTEwLjUgMy41djZsMy4wNiAzIiBjbGFzcz0iY2xzLTEiLz48L2c+PC9zdmc+)}.scylla-icon--close{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNCIgaGVpZ2h0PSIzNCIgZmlsbD0ibm9uZSI+PGcgZmlsbD0iI2ZmZiIgY2xpcC1wYXRoPSJ1cmwoI2EpIj48cGF0aCBkPSJNMTEuNjcgMjIuMTNhLjU2NC41NjQgMCAwIDEtLjM5OC0uOTYybDkuODk2LTkuODk2YS41NjMuNTYzIDAgMSAxIC43OTcuNzk3bC05Ljg5NiA5Ljg5NmEuNTU5LjU1OSAwIDAgMS0uMzk5LjE2NVoiLz48cGF0aCBkPSJNMjEuNTY2IDIyLjEzYS41NTkuNTU5IDAgMCAxLS4zOTgtLjE2NWwtOS44OTYtOS44OTZhLjU2My41NjMgMCAxIDEgLjc5Ny0uNzk3bDkuODk2IDkuODk1YS41NjQuNTY0IDAgMCAxLS4zOTkuOTYzWiIvPjxwYXRoIGQ9Ik0xNi42MTkgMzMuMjM3QzcuNDU1IDMzLjIzNyAwIDI1Ljc4MiAwIDE2LjYxOSAwIDcuNDU2IDcuNDU1IDAgMTYuNjE5IDBzMTYuNjE5IDcuNDU1IDE2LjYxOSAxNi42MTktNy40NTYgMTYuNjE4LTE2LjYyIDE2LjYxOFptMC0zMi4xMWMtOC41NDIgMC0xNS40OTIgNi45NS0xNS40OTIgMTUuNDkyIDAgOC41NDIgNi45NSAxNS40OTIgMTUuNDkyIDE1LjQ5MiA4LjU0MiAwIDE1LjQ5Mi02Ljk1IDE1LjQ5Mi0xNS40OTIgMC04LjU0Mi02Ljk1LTE1LjQ5Mi0xNS40OTItMTUuNDkyWiIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMzMuMjM3djMzLjIzN0gweiIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg==)}.scylla-icon--cloud{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8yIiB2aWV3Qm94PSIwIDAgNDMuMDQgMzIuMDMiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDpub25lO3N0cm9rZTojMWQxZDFiO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iTGF5ZXJfMyI+PHBhdGggZD0iTTQyLjU0IDQuMDZjMCAxLjY4LTMuNjMgMi40NC05IDIuNDRzLTEwLS43My0xMC0yLjRTMjcuNjcuNSAzMy4wNC41czkuNSAxLjg5IDkuNSAzLjU2Wk00Mi41NCA5LjYzYzAgMS42OC0zLjc2IDIuOTEtOS4xMiAyLjkxcy05Ljg0LTEuMjMtOS44NC0yLjkxTTQyLjU0IDE1LjM0YzAgMS42OC0zLjY4IDMuMjUtOS4wNCAzLjI1LTQgMC03LjYtLjk2LTkuMDktMi4wNE00Mi41NCAyMC42NWMwIDEuNjgtMy43MiAyLjk3LTkuMDggMi45N00yMy41NCAxNS40NlY0LjFNNDIuNTQgMjAuNzdWNC4xIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMjguMTEgMjEuMDhjLS44NyAwLTEuNjcuMjMtMi4zOS42MSAwLS4wNy4wMS0uMTQuMDEtLjIxIDAtNC44NS0zLjgzLTguOS04LjY4LTguOXMtOC44OCA0LjA1LTguODggOC45YzAgLjE3LjAyLjM0LjAzLjUxLS44NC0uNTctMS44NS0uOTEtMi45NS0uOTEtMi44OCAwLTQuNzQgMi41Ny00Ljc0IDUuNDZzMS44NiA0Ljk5IDQuNzQgNC45OWgyMi44NmMyLjg4IDAgNS41Mi0yLjI3IDUuNTItNS4xNnMtMi42My01LjI5LTUuNTItNS4yOVoiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--cloud-docs{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTYuNSAxMS41aDh2MWgtOHpNMTUuNjUgNi41NWEzLjQyIDMuNDIgMCAwIDAtMy4xNSAyIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMTAuMDYgMi44QTUuMTcgNS4xNyAwIDAgMSAxNSA2LjM1aC4yNGE0Ljg0IDQuODQgMCAwIDEgMCA5LjY3aC0xMWEzLjQ1IDMuNDUgMCAwIDEgMC02LjlBMy4xNyAzLjE3IDAgMCAxIDUgOS4yIDUuMzMgNS4zMyAwIDAgMSA0Ljg2IDhhNS4yIDUuMiAwIDAgMSA1LjItNS4ybTAtLjhhNiA2IDAgMCAwLTYgNnYuMzFhNC4yNSA0LjI1IDAgMCAwIC4xOCA4LjQ5aDExYTUuNjMgNS42MyAwIDAgMCAuMy0xMS4yNkE2IDYgMCAwIDAgMTAuMDYgMloiIHN0eWxlPSJmaWxsOiM0ZDRkNGQiLz48L2c+PC9zdmc+)}.scylla-icon--comparison{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTIsLmNscy00e2ZpbGw6bm9uZTtzdHJva2U6Z3JheX0uY2xzLTEsLmNscy0ye3N0cm9rZS1taXRlcmxpbWl0OjEwfS5jbHMtMiwuY2xzLTR7c3Ryb2tlLWxpbmVjYXA6cm91bmR9LmNscy00e3N0cm9rZS1saW5lam9pbjpyb3VuZH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik00LjUgMTMuNjN2Mi44OGg2LjA2TTIwLjUgMTMuNTR2Mi45NmwtNS41LjAxIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMTIuNSAxOC41djIuNzJNNy41IDIxLjVoMTAiIGNsYXNzPSJjbHMtMiIvPjxjaXJjbGUgY3g9IjEyLjUiIGN5PSIxNi41IiByPSIyIiBzdHlsZT0iZmlsbDpncmF5O3N0cm9rZS13aWR0aDouOTVweDtzdHJva2UtbWl0ZXJsaW1pdDoxMDtzdHJva2U6Z3JheSIvPjxwYXRoIGQ9Ik01LjA2IDEzLjU4SDMuODhBMy4xIDMuMSAwIDAgMSAuNSAxMC41aDhhMy4xNiAzLjE2IDAgMCAxLTMuNDQgMy4wOFpNMjEgMTMuNThoLTEuMTdhMy4wOSAzLjA5IDAgMCAxLTMuMzctMy4wN2g4QTMuMTYgMy4xNiAwIDAgMSAyMSAxMy41OFpNNy40NiA1LjEyYzAgLjU3LTEuMS40Ni0yLjc5LjQ2UzEuNTggNS42IDEuNTggNSAzIDQuNCA0LjY5IDQuNHMyLjc3LjE2IDIuNzcuNzJaTTEuNSA5Ljg1VjUuMzFNNy41IDEwLjM1VjUuODFNMjMuNSA1LjEyYzAgLjU3LTEuMS40Ni0yLjc5LjQ2cy0zLjA5IDAtMy4wOS0uNTRTMTkgNC40IDIwLjczIDQuNHMyLjc3LjE2IDIuNzcuNzJaTTE3LjU0IDkuODVWNS4zMU0yMy41NCAxMC4zNVY1LjgxIiBjbGFzcz0iY2xzLTQiLz48L2c+PC9zdmc+)}.scylla-icon--contact-us{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjEuMDZweH08L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJtNi4yOTggMTAuMTggMTMuODMtNy4xOTcgNC42NzYgOC45ODYtMTMuODMgNy4xOTd6IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtNi4zIDEwLjE4IDguNjMgMS41NmExLjQyIDEuNDIgMCAwIDAgMS41My0uNzRsMy42Ny04TTExLjAyIDE5LjAzbDEuNzQtNU0yNC41OSAxMS45N2wtNS4wOS0xLjQ1TTcuMDkgMTcuNTggMy45IDE5LjM0TTYuMDYgMTUuNDEuNTQgMTguMzYiIGNsYXNzPSJjbHMtMSIvPjwvc3ZnPg==)}.scylla-icon--developers-blog{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOmdyYXl9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJtNi40OCAxMC41OS0uNS4xNy41LjE2TDExIDEyLjE2VjE0bC03LTIuNDlWMTBsNy0yLjV2MS44M1pNMTQgOS4zMlY3LjVsNyAyLjV2MS41NEwxNCAxNHYtMS44M2w0LjE0LTEuMy40NC0uMTMtLjQzLS4xNFoiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik0xLjUgMi41aDIydjE2aC0xM3Y0LjE3TDYuNDYgMTguNWwtNC45Ni0uMDRWMi41eiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOi45OHB4Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--docs{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfS5jbHMtMntmaWxsOmdyYXl9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJNMy41IDIuNTFoMTYuOTR2MjAuOTFIMy41eiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTIyLjQ1IDIxLjUuMDUtMjFoLTE3YTIuMTYgMi4xNiAwIDAgMC0yIDIiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik02IDZoN3YySDZ6TTYgOWgxMXYySDZ6IiBjbGFzcz0iY2xzLTIiLz48L2c+PC9zdmc+)}.scylla-icon--enterprise{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8zIiB2aWV3Qm94PSIwIDAgMjAgMjAiPjxkZWZzPjxzdHlsZT4uY2xzLTEsLmNscy0ye2ZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9LmNscy0ye3N0cm9rZS13aWR0aDoxLjA3cHh9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0ibTEzLjYyIDcuNSAxLjg4LTEuMDggMiAyLjA4djdoMU0xNS41IDE1LjV2LTUiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik01LjUgMTUuNXYtMTJsNC0yIDQgMnYxMk05LjUgMTUuNVYxLjZNNy41IDUuNXYxME0xMS41IDUuNXYxMCIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTUuNSA4LjU0IDMuNDYgNy41bC0xLjk2Ljk2djcuMDRoLTFNMy41IDEwLjV2NU0uNSAxNy41aDE4IiBjbGFzcz0iY2xzLTEiLz48L3N2Zz4=)}.scylla-icon--enterprise-m{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIGlkPSJMYXllcl8yXzAwMDAwMDE2NzY4MDY2MDE5MjYzMjMyNzcwMDAwMDA1NDc1ODA5NTExODI4NjY2MDM2XyIgeD0iMCIgeT0iMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDMgMzEiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDQzIDMxIj48c3R5bGU+LnN0MHtmaWxsOm5vbmU7c3Ryb2tlOiMxZDFkMWI7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PGcgaWQ9IkxheWVyXzMiPjxwYXRoIGQ9Im0yOS42IDkuNSA0LTIgNi45IDQuMXYxNS45aDJNMzMuNiAyNy41VjcuNk0xNC42IDI3LjVWNC44TDIyLjUuNSAyOS42IDV2MjIuNU0yMi41IDI3LjVWMU0yNC41IDUuNmwzIDJNMjQuNSA5LjZsMyAyTTI0LjUgMTMuNmwzIDJNMjQuNSAxNy41bDMgMk0yNC41IDIxLjVsMyAyTTM1LjQgMTEuNmwzIDJNMzUuNCAxNS42bDMgMS45TTM1LjQgMTkuNWwzIDJNMzUuNCAyMy41bDMgMS45TTE4LjUgNS44djIxLjdNMTQuNiA5LjdsLTQuMS0yLjUtOCA0LjR2MTUuOWgtMk0xMC41IDI3LjVWNy4yTTEyLjUgMTEuNmwyIDFNMTIuNSAxNS42bDIgLjlNMTIuNSAxOS41bDIgMU0xMi41IDIzLjVsMi4xIDFNNi40IDEyLjR2MTUuMU0uNSAzMC41aDQyIiBjbGFzcz0ic3QwIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--events{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9LmNscy0ye2ZpbGw6Z3JheX08L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNMjIuNSAyMy41aC0yMXYtMjBoMjJ2MTUuMjEiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik00LjQyIDMuNWMwLTEuMzYgMS4wOS0yIDIuNDUtMmEyLjQ2IDIuNDYgMCAxIDEgMCA0LjkxIDIuNjEgMi42MSAwIDAgMS0xLS4yMU0xMC42NyAzLjVjMC0xLjM2IDEuMS0yIDIuNDYtMmEyLjQ2IDIuNDYgMCAwIDEgMCA0LjkxIDIuNjEgMi42MSAwIDAgMS0xLS4yMU0xNi45MyAzLjVjMC0xLjM2IDEuMS0yIDIuNDUtMmEyLjQ2IDIuNDYgMCAxIDEgMCA0LjkxIDIuNTIgMi41MiAwIDAgMS0xLS4yMSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTcgOWgzdjNIN3pNMTIgOWgzdjNoLTN6TTE3IDloM3YzaC0zek03IDE0aDN2M0g3ek0xMiAxNGgzdjNoLTN6TTE3IDE0aDN2M2gtM3oiIGNsYXNzPSJjbHMtMiIvPjxwYXRoIGQ9Ik0zLjUgMy42N3YxNi42Nk0zLjUgMjAuNDNjMCAxLjI5LjQ0IDIuMzMgMS43MyAyLjMzczIuMzMtMS45IDIuMzMtMy4xOWwxNi45NC0uMDdjMCAxLjI5LS41NSAzLjEyLTEuODMgMy4xMkg2LjMiIGNsYXNzPSJjbHMtMSIvPjwvc3ZnPg==)}.admonition.note .admonition-title:before,.admonition.tip .admonition-title:before,.scylla-icon--exclamation{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PG1hc2sgaWQ9ImEiIHdpZHRoPSIyMiIgaGVpZ2h0PSIyMiIgeD0iMSIgeT0iMSIgbWFzay10eXBlPSJhbHBoYSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTEyIDIzQzUuOSAyMyAxIDE4LjEgMSAxMlM1LjkgMSAxMiAxczExIDQuOSAxMSAxMS00LjkgMTEtMTEgMTFabTAtMjBjLTUgMC05IDQtOSA5czQgOSA5IDkgOS00IDktOS00LTktOS05WiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMiAxM2MtLjYgMC0xLS40LTEtMVY4YzAtLjYuNC0xIDEtMXMxIC40IDEgMXY0YzAgLjYtLjQgMS0xIDFaTTEyIDE3Yy0uMyAwLS41LS4xLS43LS4zLS4yLS4yLS4zLS40LS4zLS43IDAtLjEgMC0uMy4xLS40LjEtLjEuMS0uMi4yLS4zLjMtLjMuNy0uNCAxLjEtLjIuMSAwIC4xIDAgLjIuMSAwIDAgLjEuMS4yLjEuMS4xLjIuMi4yLjN2LjRjMCAuMSAwIC4zLS4xLjQtLjEuMS0uMS4yLS4yLjMtLjIuMi0uNC4zLS43LjNaIi8+PC9tYXNrPjxnIG1hc2s9InVybCgjYSkiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMjR2MjRIMHoiLz48L2c+PC9zdmc+)}.collapsible-button i,.scylla-icon--expand{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNi4wMDEiIGhlaWdodD0iMTYiPjxwYXRoIGQ9Ik01IDEzYTEgMSAwIDAgMS0uNzEtLjI5bC00LTRhMSAxIDAgMCAxIDAtMS40MWw0LTRhMSAxIDAgMCAxIDEuNDIgMS40MUwyLjQxIDhsMy4yOSAzLjI5QTEgMSAwIDAgMSA1IDEzeiIvPjxwYXRoIGQ9Ik0xMSA5SDFhMSAxIDAgMCAxIDAtMmgxMGExIDEgMCAwIDEgMCAyek0xNSAxNmExIDEgMCAwIDEtMS0xVjFhMSAxIDAgMCAxIDIgMHYxNGExIDEgMCAwIDEtMSAxeiIvPjwvc3ZnPg==)}.scylla-icon--forum{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItdXNlcnMiPjxwYXRoIGQ9Ik0xNyAyMXYtMmE0IDQgMCAwIDAtNC00SDVhNCA0IDAgMCAwLTQgNHYyIi8+PGNpcmNsZSBjeD0iOSIgY3k9IjciIHI9IjQiLz48cGF0aCBkPSJNMjMgMjF2LTJhNCA0IDAgMCAwLTMtMy44N00xNiAzLjEzYTQgNCAwIDAgMSAwIDcuNzUiLz48L3N2Zz4=)}.scylla-icon--home{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJMYXllcl81IiBkYXRhLW5hbWU9IkxheWVyIDUiPjxwYXRoIGQ9Ik0zLjUgNi4xNHYxMWExLjM4IDEuMzggMCAwIDAgMS4zNyAxLjM2aDExLjI2YTEuMzggMS4zOCAwIDAgMCAxLjM3LTEuMzd2LTExIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtMTkuNSA3LjUtOC02LjI1YTEuNTkgMS41OSAwIDAgMC0xLjk0IDBMMS41IDcuNU0xMi43MyAxOC4wMnYtNy4yMUg4LjI3djcuMjEiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--getting-started{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGcgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibTcgNC41IDguNTEgNS4wNUw3IDE0LjV2LTEweiIgc3R5bGU9ImZpbGw6IzRkNGQ0ZCIvPjxyZWN0IHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgeD0iMS41IiB5PSIuNSIgcng9IjIuNDMiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48L2c+PC9zdmc+)}.scylla-icon--glossary{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTIuNSAyLjVoMTN2MTZoLTEzeiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTE1LjU4IDE3LjIxaDEuOTJWLjVoLTEzYTIuMzQgMi4zNCAwIDAgMC0yIDIiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik00LjggMTMuOTNhMSAxIDAgMCAwIC43NS0uNDMgNiA2IDAgMCAwIC41Mi0xLjA4bDIuODctNy4wN2guMzZsMi44OCA2Ljc5YTguOTIgOC45MiAwIDAgMCAuNzIgMS40Ny43Ni43NiAwIDAgMCAuNjguMzJ2LjMySDkuNHYtLjMyYTMuMjQgMy4yNCAwIDAgMCAuODMtLjExYy4xMy0uMDYuMi0uMTkuMi0uNDJhMS41OSAxLjU5IDAgMCAwLS4xLS40NmMwLS4xMi0uMS0uMjctLjE3LS40NGwtLjMzLS43OGgtMi45Yy0uMTkuNTEtLjMxLjg1LS4zNiAxYTIuMzggMi4zOCAwIDAgMC0uMTcuNzNjMCAuMTguMTIuMzIuMzcuNGEyLjU2IDIuNTYgMCAwIDAgLjY2LjA4di4zMkg0LjhabTQuODQtMi43Mi0xLjI0LTNoLS4xMWwtMS4xNiAzWiIgc3R5bGU9ImZpbGw6IzRkNGQ0ZCIvPjwvZz48L3N2Zz4=)}.scylla-icon--infoworld{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MTB9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJNMTIgMi41SDYuNVY2YzAgMyAuNTUgNy4xNyA1IDkuNXY0IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNNi40IDQuNDRoLTRTMi41NiAxMSA4LjUgMTNNMTguNSA0LjVsNC0uMDZzLS4wNiA2LjU2LTYgOC41NiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTEyIDIuNWg2LjVWNmMwIDIuOTQtLjQgNy4wOC01IDkuNXY0TTkuNSAxOS41aDZ2MmgtNnoiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik03LjUgMjEuNWgxMHYxaC0xMHoiIHN0eWxlPSJmaWxsOmdyYXk7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48L2c+PC9zdmc+)}.scylla-icon--integrations{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibTE0LjU2IDEyLjctMS4yNS0xLjU3LTEuMzEuNzZhNiA2IDAgMCAwLTEuNjUtMWwuMDgtMS40OS0yLS40LS41MyAxLjQ0YTUuNzMgNS43MyAwIDAgMC0xLjg3LjMxbC0uODgtMS4xOS0xLjc3IDFMMy45MiAxMmE2LjMgNi4zIDAgMCAwLTEuMjIgMS40MWwtMS41LS4zNS0uNzQgMS44NyAxLjM4LjhhNi4yMyA2LjIzIDAgMCAwIDAgMS44M2wtMS40MS43Mi42NCAxLjkxIDEuNTktLjI4YTcuNjMgNy42MyAwIDAgMCAuNDguNjggNS44NiA1Ljg2IDAgMCAwIC42Ny43M2wtLjYyIDEuNDYgMS43MiAxIDEtMS4yNGE2LjQ2IDYuNDYgMCAwIDAgMS43OS4zNWwuNDYgMS41MiAyLS4zdi0xLjZhNi40MyA2LjQzIDAgMCAwIDEuNjItLjg5bDEuMy44NUwxNC40MyAyMWwtMS0xLjJhNi4yNCA2LjI0IDAgMCAwIC42OC0xLjc1bDEuNTEtLjE5LjA1LTItMS41MS0uMjZhNi4wNyA2LjA3IDAgMCAwLS42Mi0xLjgxWm0tNS4zNSA1LjUxYTEuOTMgMS45MyAwIDEgMSAuMzEtMi43MSAxLjkyIDEuOTIgMCAwIDEtLjMxIDIuNzFaIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtMjQuMzEgOC4wNS0uMTMtMS42NS0xLjI1LS4wOWE1LjI2IDUuMjYgMCAwIDAtLjY3LTEuNDRsLjc1LTEtMS4xNi0xLjE3LTEgLjc0YTUuMTggNS4xOCAwIDAgMC0xLjQzLS42NmwtLjA2LTEuMjQtMS42NS0uMTctLjMyIDEuMjVhNS43NyA1Ljc3IDAgMCAwLTEuNTIuMzhMMTUgMi4xbC0xLjM3LjkuNTggMS4xOGE0Ljg4IDQuODggMCAwIDAtLjg2IDEuMjVsLTEuMy0uMTYtLjQ1IDEuNiAxLjIyLjU1YTUuMTcgNS4xNyAwIDAgMCAwIC42OEE0LjI4IDQuMjggMCAwIDAgMTMgOWwtMS4xMS43Mi42OSAxLjUxIDEuMjgtLjM3YTQuOTQgNC45NCAwIDAgMCAxLjA3IDEuMDdsLS4zOSAxLjI2IDEuNS43MS43NC0xLjA5YTUuMDcgNS4wNyAwIDAgMCAxLjUyLjE0bC41IDEuMTkgMS42MS0uNDEtLjEzLTEuMjlhNS4xNCA1LjE0IDAgMCAwIDEuMjctLjg4bDEuMTIuNTcgMS0xLjM1LS45MS0uODhhNC45IDQuOSAwIDAgMCAuNDItMS41MlptLTYuMiAxLjQzYTEuNzQgMS43NCAwIDEgMSAxLjYtMS44NiAxLjc0IDEuNzQgMCAwIDEtMS42IDEuODZaIiBjbGFzcz0iY2xzLTEiLz48L2c+PC9zdmc+)}.scylla-icon--knowledge-base{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTojNGQ0ZDRkfS5jbHMtMXtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9LmNscy0ye3N0cm9rZS1taXRlcmxpbWl0OjEwfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJMYXllcl81IiBkYXRhLW5hbWU9IkxheWVyIDUiPjxwYXRoIGQ9Ik0xNi4yMSA2LjM4YTUuMzYgNS4zNiAwIDAgMS0xLjUxIDMuNzMgNSA1IDAgMCAwLTEuNDUgMy4zMUg4LjQ3YTUuNDEgNS40MSAwIDAgMC0xLjI4LTMuMTEgNS4zNyA1LjM3IDAgMSAxIDktMy45M1pNMTMuMjMgMTUuNjdIOC40NSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTEzLjI0IDEzLjRoLTQuOHY0LjE2YS43LjcgMCAwIDAgLjcxLjdoMy4zOGEuNy43IDAgMCAwIC43MS0uN1oiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik0xMC44NCA4LjIxYTEuNjUgMS42NSAwIDEgMSAxLjY0LTEuNjUgMS42NSAxLjY1IDAgMCAxLTEuNjQgMS42NVpNMTAuODQgOC42N3Y0LjY0IiBjbGFzcz0iY2xzLTIiLz48L2c+PC9zdmc+)}.scylla-icon--less{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNyIgaGVpZ2h0PSIxNyIgZmlsbD0ibm9uZSI+PHJlY3Qgd2lkdGg9IjE3IiBoZWlnaHQ9IjE3IiBmaWxsPSIjQjNCQUM1IiByeD0iMSIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjwvc3ZnPg==);filter:none}.scylla-icon--live-test{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtNntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLWxpbmVjYXA6cm91bmR9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48Y2lyY2xlIGN4PSIxMi41IiBjeT0iMTUiIHI9IjkuNSIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjVweDtzdHJva2UtbWl0ZXJsaW1pdDoxMDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXkiLz48cGF0aCBkPSJNMTAgLjVoNXYyaC01eiIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjFweDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7ZmlsbDpub25lO3N0cm9rZTpncmF5Ii8+PHBhdGggZD0iTTUuOCA4LjIgNC4xMyA2LjUzbDEuOC0xLjgxTDcuNiA2LjQiIHN0eWxlPSJzdHJva2Utd2lkdGg6MS4xMXB4O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbGluZWNhcDpyb3VuZDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXkiLz48cGF0aCBkPSJNMTIgNlYyLjUiIHN0eWxlPSJzdHJva2Utd2lkdGg6MS4xM3B4O3N0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6bm9uZTtzdHJva2U6Z3JheSIvPjxwYXRoIGQ9Ik0xMyA2VjIuNSIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjA4cHg7c3Ryb2tlLW1pdGVybGltaXQ6MTA7ZmlsbDpub25lO3N0cm9rZTpncmF5Ii8+PHBhdGggZD0iTTEyLjUgOC4wNlYxME0xMi41IDIwLjA0djEuODhNNy4xMyAxMC4wOGwxLjc5IDEuODhNMTYuMDQgMTcuMDhsMiAxLjg4TTcgMTguOTJsMS44OC0xLjg4TTE2LjEzIDExLjk2bDEuNzktMS44MyIgY2xhc3M9ImNscy02Ii8+PGVsbGlwc2UgY3g9IjEyLjUiIGN5PSIxNC4zNiIgcng9IjEuNSIgcnk9IjEuMzYiIHN0eWxlPSJmaWxsOmdyYXkiLz48cGF0aCBkPSJtMTIuNjMgMTQuNTQgMi41IDYuMzgiIGNsYXNzPSJjbHMtNiIvPjwvZz48L3N2Zz4=)}.scylla-icon--mail-list{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItbWFpbCI+PHBhdGggZD0iTTQgNGgxNmMxLjEgMCAyIC45IDIgMnYxMmMwIDEuMS0uOSAyLTIgMkg0Yy0xLjEgMC0yLS45LTItMlY2YzAtMS4xLjktMiAyLTJ6Ii8+PHBhdGggZD0ibTIyIDYtMTAgN0wyIDYiLz48L3N2Zz4=)}.scylla-icon--manager{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtM3tmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDouOTdweH0uY2xzLTR7ZmlsbDpncmF5fTwvc3R5bGU+PC9kZWZzPjxwYXRoIGlkPSJDYWxxdWVfMiIgZD0iTTE4IDJoNXYyMkgzVjJoNC45MiIgZGF0YS1uYW1lPSJDYWxxdWUgMiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQiLz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik04IDBoMTB2NEg4eiIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjA3cHg7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZCIvPjxwYXRoIGQ9Ik03IDloM3YzSDd6TTcgMTZoM3YzSDd6IiBjbGFzcz0iY2xzLTMiLz48cGF0aCBkPSJNMTIuNSA5LjVoN3YyaC03ek0xMi41IDE2LjVoN3YyaC03eiIgY2xhc3M9ImNscy00Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--memory-management{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH0uY2xzLTJ7c3Ryb2tlLXdpZHRoOjEuMTNweH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxyZWN0IHdpZHRoPSIxNSIgaGVpZ2h0PSIxNSIgeD0iNS41IiB5PSI1LjUiIGNsYXNzPSJjbHMtMSIgcng9IjIuNzQiIHJ5PSIyLjc0Ii8+PHBhdGggZD0iTTkuNSA5LjVoN3Y3aC03eiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTguNSA1LjV2LTRNMTEuNSA1LjV2LTRNMTQuNSA1LjV2LTRNMTcuNSA1LjV2LTRNOC41IDI0LjV2LTRNMTEuNSAyNC41di00TTE0LjUgMjQuNXYtNE0xNy41IDI0LjV2LTRNMjAuNSA4LjVoNE0yMC41IDExLjVoNE0yMC41IDE0LjVoNE0yMC41IDE3LjVoNE0xLjUgOC41aDRNMS41IDExLjVoNE0xLjUgMTQuNWg0TTEuNSAxNy41aDQiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.scylla-icon--monitoring{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGcgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTUuNTUgMTAuODlhMy44MyAzLjgzIDAgMCAxLS4xNS0zLjc2IiBzdHlsZT0ic3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZTpncmF5O2ZpbGw6bm9uZSIvPjxyZWN0IHdpZHRoPSIzLjA1IiBoZWlnaHQ9IjEwLjgiIHg9IjE3LjYzIiB5PSIxNC4wMSIgcng9Ii41NyIgcnk9Ii41NyIgc3R5bGU9InN0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6Z3JheTtzdHJva2Utd2lkdGg6Ljk1cHg7c3Ryb2tlOmdyYXkiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxOS4xNTggMTkuNDA1KSIvPjxjaXJjbGUgY3g9IjguNSIgY3k9IjkiIHI9IjciIHN0eWxlPSJzdHJva2Utd2lkdGg6MnB4O3N0cm9rZS1taXRlcmxpbWl0OjEwO3N0cm9rZTpncmF5O2ZpbGw6bm9uZSIvPjxwYXRoIGQ9Im0xNi4wNSAxNi4zOS0yLjI4LTIuMjgiIHN0eWxlPSJzdHJva2UtbWl0ZXJsaW1pdDoxMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2U6Z3JheTtmaWxsOm5vbmUiLz48L2c+PC9zdmc+)}.scylla-icon--networking{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTB9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48Y2lyY2xlIGN4PSIxMi41IiBjeT0iMTIuNSIgcj0iNCIgc3R5bGU9InN0cm9rZS13aWR0aDouOTRweDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48Y2lyY2xlIGN4PSI1IiBjeT0iMyIgcj0iMi41IiBjbGFzcz0iY2xzLTIiLz48Y2lyY2xlIGN4PSIxOSIgY3k9IjIwIiByPSIyLjUiIGNsYXNzPSJjbHMtMiIvPjxjaXJjbGUgY3g9IjIyIiBjeT0iNi42IiByPSIyLjUiIGNsYXNzPSJjbHMtMiIvPjxjaXJjbGUgY3g9IjQuNSIgY3k9IjIyIiByPSIyLjUiIGNsYXNzPSJjbHMtMiIvPjxwYXRoIGQ9Im02LjgzIDUuNSAzLjI1IDQuMzNNMjAuMjMgNy44NSAxNS4zMyAxMU05LjgzIDE1LjA4bC00LjA5IDUuODRNMTQuNTggMTUuMzNsMyAzLjA5IiBjbGFzcz0iY2xzLTIiLz48Y2lyY2xlIGN4PSIxMi41IiBjeT0iMTIuNSIgcj0iMS41IiBzdHlsZT0iZmlsbDpncmF5Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--news{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTMgMTUuMTcgMTYuMzEgMy44MmExLjQ4IDEuNDggMCAwIDEgMi4yMi40Nmw1LjE1IDkuNjVhMS40NiAxLjQ2IDAgMCAxLS45MyAyLjEyTDUuNjkgMTkuOVpNOC43MSAxOS4zM2wuNzYgMi4yMmExLjUxIDEuNTEgMCAwIDAgMS44NSAxbDMuNTgtMS4wNmExLjUgMS41IDAgMCAwIDEtMS44NkwxNS40NSAxOE01LjU0IDIwbC0xLjgzIDFhLjkyLjkyIDAgMCAxLTEuMjUtLjM3TC42MSAxNy40OUEuOTIuOTIgMCAwIDEgMSAxNi4yNGwxLjgzLTFNOC41IDE0bDcuMzgtNS41IiBjbGFzcz0iY2xzLTEiLz48L3N2Zz4=)}.scylla-icon--newsletter{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1taXRlcmxpbWl0OjEwfS5jbHMtMntzdHJva2UtbGluZWNhcDpyb3VuZH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik0xOS41IDkuNWgzdjEyaC0yMHYtMTJoMyIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTIuNjUgOS44NCA5Ljg1IDYuODggOC42My02Ljg4IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtNS41IDcuNS0zIDJNMTQuMzUgMy44NmwtMS40Ni0xLjA5LTEuNDcgMS4wOU0yMS41IDkuNWwtMi0yTTE5LjUgMTEuNXYtN2gtMTR2Ny40NyIgY2xhc3M9ImNscy0yIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--nsql-guides{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGcgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHJlY3Qgd2lkdGg9IjEuMTUiIGhlaWdodD0iOS43MiIgeD0iNC4zNyIgeT0iMTMuNzEiIHJ4PSIuNTQiIHJ5PSIuNTQiIHN0eWxlPSJzdHJva2U6Z3JheTtzdHJva2UtbWl0ZXJsaW1pdDoxMDtmaWxsOmdyYXk7c3Ryb2tlLXdpZHRoOjEuMDlweCIgdHJhbnNmb3JtPSJyb3RhdGUoNDUgNC45NDggMTguNTcpIi8+PGNpcmNsZSBjeD0iMTIuMjUiIGN5PSIxMi4yNSIgcj0iNC43NSIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjVweDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48cGF0aCBkPSJNOC41IDIwLjV2M2gxNXYtMjFoLTE1djIiIHN0eWxlPSJzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2Utd2lkdGg6MS4wNnB4O2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbWl0ZXJsaW1pdDoxMCIvPjwvZz48L3N2Zz4=)}.scylla-icon--open-source{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfS5jbHMtMntmaWxsOmdyYXl9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJNLjMxIDIxLjUxIDUgMTkuNjlhMi4zNyAyLjM3IDAgMCAxIDEuODguMTlsNS4yNCAxLjY4YTIuMjMgMi4yMyAwIDAgMCAyLS4xMmw5LjUtNC43NWMuOC0uNDQgMS42NC0xLjMxIDEuMTMtMS45MWEyLjM0IDIuMzQgMCAwIDAtMi42NC0uNDJMMTggMTYuMDkiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Im0uMjUgMTUuNjkgNC44OC0xLjIxYzEuMjUtLjMgMi4xNy0uNjMgMy40NC0uMTNhMTUuMjEgMTUuMjEgMCAwIDAgNCAxLjFoNC41MmMuODUgMCAuOTUuNTQuOTUgMS4xM2ExIDEgMCAwIDEtMS4wOCAxIDY1Ljg2IDY1Ljg2IDAgMCAxLTctLjMxIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNOC41NiA5LjY4di0uODFjMC0uOTEtLjM4LTEuMjEtMS4yOS0xLjIxSDdWNi4zaC4zMWMuOTEgMCAxLjI5LS4zIDEuMjktMS4yMXYtLjgxYzAtMS4yLjY2LTEuOTIgMi44Mi0yLjN2MS4xNmMtMS4yNC4zNS0xLjQzLjY4LTEuNDMgMS40di44N0ExLjUyIDEuNTIgMCAwIDEgOC43NSA3IDEuNTIgMS41MiAwIDAgMSAxMCA4LjU2di44N2MwIC43MS4xOSAxIDEuNDMgMS40VjEyYy0yLjIxLS4zNS0yLjg3LTEuMTItMi44Ny0yLjMyWk0xNy40MyA0LjN2LjgxYzAgLjkxLjM3IDEuMjEgMS4yOSAxLjIxSDE5djEuMzZoLS4zMWMtLjkyIDAtMS4yOS4zLTEuMjkgMS4yMXYuODFjMCAxLjItLjY1IDItMi44MSAyLjM1di0xLjJjMS4yNS0uMzYgMS40NC0uNjkgMS40NC0xLjR2LS44N0ExLjUzIDEuNTMgMCAwIDEgMTcuMjUgNyAxLjUzIDEuNTMgMCAwIDEgMTYgNS40M3YtLjg3YzAtLjcyLS4xOS0xLTEuNDQtMS40VjJjMi4yMi4zOCAyLjg3IDEuMSAyLjg3IDIuM1oiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.scylla-icon--operator{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjQuODEgMS4wMSAyOC4zMiAyNy42NCI+PHBhdGggZD0iTTMyLjUyIDE4cy0uMDkgMC0uMDktLjA1LS4wOCAwLS4xNyAwYTIuMTkgMi4xOSAwIDAgMC0uNTEgMCAuNDcuNDcgMCAwIDEtLjI2LS4wNSA5LjI5IDkuMjkgMCAwIDEtMS40OS0uMzIuNTQuNTQgMCAwIDEtLjMtLjMxbC0uMzQtLjA4YTExLjI1IDExLjI1IDAgMCAwLS4xOC0zLjc5IDExLjU1IDExLjU1IDAgMCAwLTEuNS0zLjUybC4yNi0uMjZhLjU5LjU5IDAgMCAxIC4xMy0uMzkgNy43MyA3LjczIDAgMCAxIDEuMi0uODZsLjI2LS4xMy40Ny0uM3MuMDkgMCAuMTMtLjA4IDAtLjA1IDAtLjA5YS44NC44NCAwIDAgMCAuMTctMS4yLjc4Ljc4IDAgMCAwLS42LS4zIDEgMSAwIDAgMC0uNi4yMWMtLjA1LjA1LS4wOS4wOS0uMTMuMDlhMy4wOCAzLjA4IDAgMCAwLS4zNS4zOWMwIC4wOC0uMTMuMTMtLjE3LjE3YTUuNjQgNS42NCAwIDAgMS0xLjA3Ljk0LjU4LjU4IDAgMCAxLS4yNi4wOS4yNS4yNSAwIDAgMS0uMTcgMGgtLjA1bC0uMzQuMjEtMS4wOC0xYTExIDExIDAgMCAwLTUuNjUtMi4yN3YtLjM0YS42LjYgMCAwIDEtLjIyLS4zNEE4LjE4IDguMTggMCAwIDEgMTkuNjYgM3YtLjI1YzAtLjA4LjA1LS4zNS4wOS0uNTJ2LS4zMWEuODIuODIgMCAwIDAtMS40Ni0uNi44Ni44NiAwIDAgMC0uMjYuNnYuMjJhMS44MiAxLjgyIDAgMCAwIC4wOS41MS41OS41OSAwIDAgMSAwIC4yNlYzYTguODIgOC44MiAwIDAgMSAuMDggMS40Ny41OS41OSAwIDAgMS0uMjEuMzRWNS4yNGMtLjQ4IDAtMSAuMTMtMS40Ny4yMmExMC4xNiAxMC4xNiAwIDAgMC01LjI4IDNMMTEgOC4yNGgtLjE3YS43My43MyAwIDAgMS0uMjYtLjA5IDcuOCA3LjggMCAwIDEtMS4wNy0xYzAtLjA4LS4xMy0uMTMtLjE3LS4xN3MtLjI1LS4yLS4zMy0uMzMtLjA4IDAtLjEzLS4wOHYtLjA1YTEgMSAwIDAgMC0uNi0uMjEuNjQuNjQgMCAwIDAtLjYuMy45MS45MSAwIDAgMCAuMTcgMS4yczAgLjA1IDAgLjA1LjA5LjA4LjEzLjA4YTUgNSAwIDAgMCAuNDcuMjZsLjI2LjEzYTYuNjEgNi42MSAwIDAgMSAxLjIxLjg2LjQ3LjQ3IDAgMCAxIC4xMy4zOXYtLjA1bC4yNS4yNmEyLjUzIDIuNTMgMCAwIDEtLjEzLjIyIDEwLjIgMTAuMiAwIDAgMC0xLjUgN2wtLjM1LjA5YzAgLjEzLS4xNy4yMS0uMy4zYTguNTYgOC41NiAwIDAgMS0xLjQ2LjI2LjU5LjU5IDAgMCAwLS4yNiAwaC0uNTJjLS4xOCAwLS4wOC4wNS0uMTcuMDVoLS4wOGEuODQuODQgMCAwIDAtLjY5IDEgLjc5Ljc5IDAgMCAwIC44Ni42LjM5LjM5IDAgMCAwIC4yMSAwSDYuMTJhMy42MSAzLjYxIDAgMCAwIC40Ny0uMTcuNjUuNjUgMCAwIDEgLjI2LS4wOCA3LjY1IDcuNjUgMCAwIDEgMS40Mi0uMzkuNDkuNDkgMCAwIDEgLjM1LjEzaC4zOWExMC4zMiAxMC4zMiAwIDAgMCAzLjUzIDUgNi4zMSA2LjMxIDAgMCAwIDEuMTYuNzdsLS4yMi4zYS41MS41MSAwIDAgMSAwIC40MyA2LjU0IDYuNTQgMCAwIDEtLjY5IDEuMjR2LjA1YS43OC43OCAwIDAgMS0uMTcuMjFjLS4wOS4wOS0uMTcuMjYtLjMuNDNzMCAuMDktLjA5LjEzIDAgLjA1IDAgLjA1YS44OC44OCAwIDAgMCAuMzQgMS4xNi45LjkgMCAwIDAgLjMuMDggMSAxIDAgMCAwIC44Mi0uNTFzMC0uMDguMDktLjEzLjEzLS4zLjE3LS40N2wuMDktLjI2YTcuMDcgNy4wNyAwIDAgMSAuNTYtMS4zMy42Mi42MiAwIDAgMSAuMzQtLjI2bC4xNy0uMzVhMTAuMDUgMTAuMDUgMCAwIDAgMy43NS42OSA4LjQ1IDguNDUgMCAwIDAgMi4zMi0uMyAxMS40NiAxMS40NiAwIDAgMCAxLjM3LS4zOWwuMTguMzFhLjYyLjYyIDAgMCAxIC4zNC4yNiA3LjA3IDcuMDcgMCAwIDEgLjU2IDEuMzNsLjA5LjI2YTEuMzEgMS4zMSAwIDAgMCAuMTcuNDdjMCAuMDUgMCAuMDkuMDkuMTNhMSAxIDAgMCAwIC44Mi41MSAxLjA1IDEuMDUgMCAwIDAgLjM0LS4wOC43Ni43NiAwIDAgMCAuMzktLjQ4IDEuMDggMS4wOCAwIDAgMC0uMDUtLjY0LjIuMiAwIDAgMC0uMDgtLjEzIDEuNTMgMS41MyAwIDAgMC0uMzEtLjQzLjY1LjY1IDAgMCAwLS4xNy0uMjJ2LS4wOWE1LjIyIDUuMjIgMCAwIDEtLjY5LTEuMjQuNTEuNTEgMCAwIDEgLjA1LS40M2wtLjEzLS4zNEExMC42OCAxMC42OCAwIDAgMCAyOSAxOC44MmwuMzQuMDV2LS4wNWEuNTQuNTQgMCAwIDEgLjM1LS4xMyA3LjgyIDcuODIgMCAwIDEgMS4zOC4zOS42Mi42MiAwIDAgMCAuMjYuMDkgMi40MiAyLjQyIDAgMCAwIC40Ny4yMXMuMDkgMCAuMTcgMGguMDlhLjM5LjM5IDAgMCAwIC4yMSAwIC45NC45NCAwIDAgMCAuODYtLjYgMSAxIDAgMCAwLS43Ny0uOVptLTEyLjQzLTEuMzMtMS4xNi41Ni0xLjE2LS41Ni0uMy0xLjI1LjgxLTFoMS4yOWwuODIgMVptNy0yLjc5YTggOCAwIDAgMSAuMTcgMi43MWwtNC4xNS0uNzVjLS4zOC0uMDgtLjY4LS45LS43MS0xLjIyYTQgNCAwIDAgMSAuMjEtLjc0bDMuNDUtMi41NGE4LjU4IDguNTggMCAwIDEgMS4wNCAyLjU0Wm0tMi4zMS00LjEzLTMuMjIgMi42OWExLjI4IDEuMjggMCAwIDEtMS4yNS0uMzdjLS4wOS0uMDktLjM3LS4yNS0uMzctLjM4VjcuNDNhOC4wNyA4LjA3IDAgMCAxIDQuODYgMi4zMlpNMTcgNy41NmwxLS4xOC0uMDYgNC4zMWMwIC4zOC0uNjQuNjgtMSAuNjhhMS4xMSAxLjExIDAgMCAxLS4zNS0uMDhMMTMgOS43NWE4LjQxIDguNDEgMCAwIDEgNC0yLjE5Wm0tNS4yNCAzLjc4IDMuMzcgMi40Ny4zMi41M2ExLjE0IDEuMTQgMCAwIDEtLjI1IDEgLjc4Ljc4IDAgMCAxLS4zOC4zMWwtNC4zMS45YTkgOSAwIDAgMSAxLjI0LTUuMjFaTTExIDE4LjYxbDQuMS0xLjIzYy4zNSAwIC44NC43MS44OSAxLjA2YS41MS41MSAwIDAgMS0uMDUuNDNsLTEuNjMgMy45NUE4LjQxIDguNDEgMCAwIDEgMTEgMTguNjFabTkuNzYgNS4zM2E4LjY3IDguNjcgMCAwIDEtMS44NS4yMSA5LjU5IDkuNTkgMCAwIDEtMi43MS0uNDNsMS42Ni00Yy4yMS0uMjYgMS0uMiAxLjMxIDBhMi40OCAyLjQ4IDAgMCAxIC4zNC4zbDIuMDcgMy43NGE1LjcyIDUuNzIgMCAwIDAtLjguMThaTTI2IDIwLjJhOC4zNiA4LjM2IDAgMCAxLTIuNTggMi41OGwtMS45Mi0zLjcyYTEuMTUgMS4xNSAwIDAgMSAuNDEtMWMuMjEtLjI1LjU5LS41OS43MS0uNTlsNC4yMiAxLjA2QTYuMjcgNi4yNyAwIDAgMSAyNiAyMC4yWiIgZGF0YS1uYW1lPSJDYWxxdWUgMiIgc3R5bGU9ImZpbGw6IzRkNGQ0ZCIvPjwvc3ZnPg==)}.scylla-icon--overview{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTIyLjYxIDMuNDVDMjIuNjEgNS4wNiAxOCA2LjUgMTIuNSA2LjVzLTEwLTEuNDQtMTAtMyA0LjUtMyAxMC0zIDEwLjExIDEuMzMgMTAuMTEgMi45NVpNMjIuNjEgOS40NGMwIDEuNjEtNC42NCAzLjA2LTEwLjExIDMuMDZzLTEwLTEuNDUtMTAtMy4wNk0yMi42MSAxNS41MWMwIDEuNjItNC42NCAzLTEwLjExIDNzLTEwLTEuMzctMTAtM00yMi42MSAyMS41OWMwIDEuNjItNC42NCAyLjkxLTEwLjExIDIuOTFzLTEwLTEuMjktMTAtMi45MU0yLjUgMjEuNDdWMy40NU0yMi41IDIxLjQ3VjMuNDUiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--partners{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTE4LjUgOC4yNmgtNC43MmwtMS4yMyAxLjI3TTIuMzkgMTUuMDkuMTUgMTMuNzRsNC44Ny04LjQyIDIuMjQgMS4zNC00Ljg3IDguNDN6TTIyLjU5IDE1LjA5bDIuMjQtMS4zNS00Ljg2LTguNDItMi4yNCAxLjM0IDQuODYgOC40M3pNMTAuNzEgMTUuMjZsLTIuOTMgMi4yMU0xMi4xOCAxNi40bC0yLjkzIDIuMjFNMTMuNjggMTcuNTNsLTIuOTMgMi4yMiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTYuMzggOC4zaDMuNzhhMi4yNyAyLjI3IDAgMCAxIDEuMzcuNDdjMS4yNiAxIDQuMDkgMy4xOCA0LjQ4IDMuNTZzLTEuMTQgMS42OC0yLjI3IDEuMWExOC4zNCAxOC4zNCAwIDAgMC0yLjExLS45Mi41Ny41NyAwIDAgMC0uNTYuMDlsLTQuNzkgMy44OUwxMi4zMyAyMWw5LjQ2LTcuMDlNMy4yNCAxNC4yMmwzLjQgMS44NSIgY2xhc3M9ImNscy0xIi8+PC9zdmc+)}.scylla-icon--plus{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNyIgaGVpZ2h0PSIxNyIgZmlsbD0ibm9uZSI+PHJlY3Qgd2lkdGg9IjE3IiBoZWlnaHQ9IjE3IiBmaWxsPSIjQjNCQUM1IiByeD0iMSIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==);filter:none}.scylla-icon--pricing{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfMiIgZGF0YS1uYW1lPSJDYWxxdWUgMiI+PHBhdGggZD0ibTIxLjczIDctMi40MS01LjEyYTIuNTIgMi41MiAwIDAgMC0yLjgyLTFsLTYuMDggMi4wNEExLjY5IDEuNjkgMCAwIDAgOS41MSA0TDMuOTMgMTkuMjlhMS4wNiAxLjA2IDAgMCAwIC42NCAxLjE3bDEwLjM0IDMuNzZhMSAxIDAgMCAwIDEuMjItLjQzbDUuNTgtMTUuMzNBMS44NyAxLjg3IDAgMCAwIDIxLjczIDdaIiBjbGFzcz0iY2xzLTEiLz48Y2lyY2xlIGN4PSIxNS43MyIgY3k9IjUuODkiIHI9IjIiIGNsYXNzPSJjbHMtMSIvPjx0ZXh0IHN0eWxlPSJmb250LXNpemU6MTJweDtmaWxsOmdyYXk7Zm9udC1mYW1pbHk6Um9ib3RvLU1lZGl1bSxSb2JvdG8iIHRyYW5zZm9ybT0icm90YXRlKDIwIC00OC4yNDQgMzAuNjcpIj4kPC90ZXh0PjwvZz48L3N2Zz4=)}.scylla-icon--release-note{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDouOTFweH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzIiIGRhdGEtbmFtZT0iQ2FscXVlIDIiPjxwYXRoIGQ9Ik0yMS41IDI0LjVoLTE3VjUuN0w4Ljk1LjU0IDIxLjUuNXYyNHoiIHN0eWxlPSJzdHJva2Utd2lkdGg6LjlweDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kIi8+PHBhdGggZD0iTTQuNjUgNS41SDkuNVYxTTcuNSA4LjVoMTFNNy41IDExLjVoMTFNNy41IDE0LjVoMTFNNy41IDE3LjVoMTFNNy41IDIwLjVoMTEiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.scylla-icon--resource-center{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfS5jbHMtMntmaWxsOmdyYXl9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJNNS41IDIuNWg2LjkxbC4wOSAyMGgtN3YtMjB6IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNOCA0aDJ2MTAuOTdMOCAxNVY0eiIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTUuMzYgMi4yOSAyLjUgMy41djE4bDIuNzkgMS4xNCIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTEyLjU3IDIxLjg2IDEuNTcuNzUiIHN0eWxlPSJzdHJva2Utd2lkdGg6LjY4cHg7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZCIvPjxwYXRoIGQ9Im0xNC4xMSAyLjUtMS41NC41NyIgc3R5bGU9InN0cm9rZS13aWR0aDouODVweDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kIi8+PGNpcmNsZSBjeD0iOSIgY3k9IjE5IiByPSIxIiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMTQuNSAyLjVoNi45NGwuMDYgMjBoLTd2LTIweiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTE3IDRoMnYxMC45N0wxNyAxNVY0eiIgY2xhc3M9ImNscy0yIi8+PGNpcmNsZSBjeD0iMTgiIGN5PSIxOSIgcj0iMSIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTEyLjYgMi43M2gxLjY3VjIyLjZIMTIuNnpNMi41OCAyMS41bDIuNzUgMS4xVjIuNzNsLTIuNjYuOTQtLjA5IDE3LjgzeiIgY2xhc3M9ImNscy0yIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--roadmap{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTpncmF5fS5jbHMtMXtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOi45OHB4fS5jbHMtMntzdHJva2UtbWl0ZXJsaW1pdDoxMH0uY2xzLTN7ZmlsbDpncmF5fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibS41IDQuNSA4LTMgOCA0IDgtM3YxN2wtOCAzLTgtNC04IDN2LTE3ek04LjUgMS41VjE4TTE2LjUgNS41VjIyIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMi41IDEzIDcgMTYuNU03IDEybC00LjUgNS41TTE4LjUgOGw0LjUgMy41TTIzIDdsLTQuNSA1LjUiIGNsYXNzPSJjbHMtMiIvPjxwYXRoIGQ9Ik0xMCAxM2gxdjFoLTF6TTEyIDEyaDF2MWgtMXpNMTQgMTFoMXYxaC0xeiIgY2xhc3M9ImNscy0zIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--search{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTEwLjUgMThhNy41IDcuNSAwIDEgMCAwLTE1IDcuNSA3LjUgMCAwIDAgMCAxNVpNMjEgMjFsLTUuMi01LjIiLz48L3N2Zz4=)}.scylla-icon--slack{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tISBGb250IEF3ZXNvbWUgUHJvIDYuMC4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlIChDb21tZXJjaWFsIExpY2Vuc2UpIENvcHlyaWdodCAyMDIyIEZvbnRpY29ucywgSW5jLi0tPjxwYXRoIGQ9Ik05NC4xMiAzMTUuMWMwIDI1LjktMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDZTMCAzNDEgMCAzMTUuMWMwLTI1LjkgMjEuMTYtNDcuMDYgNDcuMDYtNDcuMDZoNDcuMDZ2NDcuMDZ6bTIzLjcyIDBjMC0yNS45IDIxLjE2LTQ3LjA2IDQ3LjA2LTQ3LjA2czQ3LjA2IDIxLjE2IDQ3LjA2IDQ3LjA2djExNy44NGMwIDI1LjktMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDZzLTQ3LjA2LTIxLjE2LTQ3LjA2LTQ3LjA2VjMxNS4xem00Ny4wNi0xODguOThjLTI1LjkgMC00Ny4wNi0yMS4xNi00Ny4wNi00Ny4wNlMxMzkgMzIgMTY0LjkgMzJzNDcuMDYgMjEuMTYgNDcuMDYgNDcuMDZ2NDcuMDZIMTY0Ljl6bTAgMjMuNzJjMjUuOSAwIDQ3LjA2IDIxLjE2IDQ3LjA2IDQ3LjA2cy0yMS4xNiA0Ny4wNi00Ny4wNiA0Ny4wNkg0Ny4wNkMyMS4xNiAyNDMuOTYgMCAyMjIuOCAwIDE5Ni45czIxLjE2LTQ3LjA2IDQ3LjA2LTQ3LjA2SDE2NC45em0xODguOTggNDcuMDZjMC0yNS45IDIxLjE2LTQ3LjA2IDQ3LjA2LTQ3LjA2IDI1LjkgMCA0Ny4wNiAyMS4xNiA0Ny4wNiA0Ny4wNnMtMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDZoLTQ3LjA2VjE5Ni45em0tMjMuNzIgMGMwIDI1LjktMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDYtMjUuOSAwLTQ3LjA2LTIxLjE2LTQ3LjA2LTQ3LjA2Vjc5LjA2YzAtMjUuOSAyMS4xNi00Ny4wNiA0Ny4wNi00Ny4wNiAyNS45IDAgNDcuMDYgMjEuMTYgNDcuMDYgNDcuMDZWMTk2Ljl6TTI4My4xIDM4NS44OGMyNS45IDAgNDcuMDYgMjEuMTYgNDcuMDYgNDcuMDYgMCAyNS45LTIxLjE2IDQ3LjA2LTQ3LjA2IDQ3LjA2LTI1LjkgMC00Ny4wNi0yMS4xNi00Ny4wNi00Ny4wNnYtNDcuMDZoNDcuMDZ6bTAtMjMuNzJjLTI1LjkgMC00Ny4wNi0yMS4xNi00Ny4wNi00Ny4wNiAwLTI1LjkgMjEuMTYtNDcuMDYgNDcuMDYtNDcuMDZoMTE3Ljg0YzI1LjkgMCA0Ny4wNiAyMS4xNiA0Ny4wNiA0Ny4wNiAwIDI1LjktMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDZIMjgzLjF6Ii8+PC9zdmc+)}.scylla-icon--stack-overflow{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIzMSIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMjEuOTQ5LjExMyAyLjA0MyAxMS42Ny0yLjUxNC40MzJMMTkuNDM1LjU0NSAyMS45NS4xMTRabS0xNy45NzMgMjYgMTEuOTQ1LS4wMDUtLjAwMi0yLjUzLTExLjk0NC4wMDYuMDAxIDIuNTNabTEyLjIzMi01Ljc3N0w0LjMxNSAxOS4yNWwtLjIzNSAyLjUyIDExLjg5NCAxLjA4NS4yMzQtMi41MTlabS0xMC43NS02LjM3NSAxMS41MzUgMy4wNzQtLjY2MiAyLjQ0My0xMS41MzUtMy4wNzUuNjYyLTIuNDQyWm0xMy4wNC4xOEw4LjIxMiA4LjEyNmwtMS4yOTcgMi4xNzggMTAuMjg5IDYuMDE3IDEuMjk2LTIuMTc4Wm0tNC4yMDYtMTEuNTYgNi43MyA5Ljc4Ny0yLjEwOCAxLjQyNC02LjczLTkuNzg1IDIuMTA4LTEuNDI1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTE3Ljk1IDE3Ljc4OVYyOC4xM0gyLjI4MlYxNy43ODlILjI0M3YxMi4zMjZIMTkuOThWMTcuNzg5aC0yLjAzWiIvPjwvc3ZnPg==)}.scylla-icon--summit{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6IzRkNGQ0ZDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0ibTE2LjUgMjIgMS02LjUtMTAgLjAzIDEgNi40MyIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTMuNDYgMTJBNS42OSA1LjY5IDAgMCAxIDUgNy41IiBzdHlsZT0ic3Ryb2tlLXdpZHRoOjEuMXB4O3N0cm9rZTojNGQ0ZDRkO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtmaWxsOm5vbmUiLz48cGF0aCBkPSJNMTQuNjIgNWEyLjMzIDIuMzMgMCAwIDEtMi4yNSAyLjVjLTEuMzMgMC0yLTEuMTItMS45NS0yLjQ0cy43LTIuNSAyLTIuNDhBMi4yNyAyLjI3IDAgMCAxIDE0LjYyIDVaTTE3LjU4IDEyYTMuMjMgMy4yMyAwIDAgMC0zLjQ2LTMuNUgxMUEzLjI2IDMuMjYgMCAwIDAgNy41IDEyIiBjbGFzcz0iY2xzLTEiLz48Y2lyY2xlIGN4PSI0Ljk0IiBjeT0iNi45NiIgcj0iMS4wMSIgc3R5bGU9ImZpbGw6IzRkNGQ0ZDtzdHJva2Utd2lkdGg6MS4xcHg7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kIi8+PHBhdGggZD0iTTcuNTQgMTguNUg0LjVsLTItNmgyMGwtMiA2aC0zIiBjbGFzcz0iY2xzLTEiLz48L3N2Zz4=)}.scylla-icon--support{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTE4LjE5IDcuNWExMCAxMCAwIDAgMSAuMjEgMi4wN2MwIDQuMzYtMi42MyA2LjkzLTUuOSA2Ljkzcy01Ljk0LTIuNTctNS45NC02LjkzYTEwLjUxIDEwLjUxIDAgMCAxIC4yMi0yLjEyIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNNy42NyAyLjIzQTYuNTggNi41OCAwIDAgMSAxMi41LjVhNS42NSA1LjY1IDAgMCAxIDQuMjkgMS43YzEuOTMgMS45NCAyLjM1IDUuMDcgMi40MyA2LjcyYTEuNDkgMS40OSAwIDAgMC0uNzkuMDUgOC42OCA4LjY4IDAgMCAwLS4wOC0xLjE2aDBhNS41MyA1LjUzIDAgMCAxLTEuNzctMi4zNEwxNi40OSA1bC0uMzguMjJBMTkgMTkgMCAwIDEgNi44IDcuMzhhLjUyLjUyIDAgMCAwLS40Mi4xNmMtLjIzLjI0LS4xNS42NS0uMDcgMS4wOCAwIC4xMSAwIC4yMi4wNS4zMmExLjQgMS40IDAgMCAwLS41OCAwYy0uMS0xLjQ1LS4wNi00LjY4IDEuODktNi43MVpNNi4zOCA5Yy0uNjUtLjA4LTEgLjEtMS4xNC43OWEyLjA2IDIuMDYgMCAwIDAgMS4zNyAyLjI5TTE4LjU2IDljLjY1LS4wOCAxLjA1LjEgMS4xNC43OWEyLjA2IDIuMDYgMCAwIDEtMS4zNyAyLjI5TTkuNSAxOC4yM1YxNS41TTE1LjUgMTUuNXYyLjczTTIuNSAyNC4xNmMuMjQtMiAuNTktMy42MyAyLjQzLTQuNDlhMjQuMjkgMjQuMjkgMCAwIDEgNC44Mi0xLjM3TTIyLjUgMjQuMzNjLS4yNC0yLS40Mi0zLjgtMi4yNi00LjY2YTI0LjI5IDI0LjI5IDAgMCAwLTQuODItMS4zNyIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTE1LjM5IDE4LjM5YTQuMzcgNC4zNyAwIDAgMS0yLjkxIDEuMDcgNC40MiA0LjQyIDAgMCAxLTIuODktMS4wNSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTExIDEzaDN2MmgtM3oiIHN0eWxlPSJmaWxsOmdyYXkiLz48cGF0aCBkPSJNMTguMDcgMTJhOS4yMSA5LjIxIDAgMCAxLTUuNTMgMi4wNyIgc3R5bGU9InN0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6bm9uZTtzdHJva2U6Z3JheSIvPjwvZz48L3N2Zz4=)}.scylla-icon--tech-talks{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTguMzkgNC41SDIzLjV2MTNoLTE1IiBjbGFzcz0iY2xzLTEiLz48Y2lyY2xlIGN4PSI0LjUiIGN5PSI2LjUiIHI9IjIiIHN0eWxlPSJzdHJva2UtbWl0ZXJsaW1pdDoxMDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXkiLz48cGF0aCBkPSJNMS41IDkuNWgybC44Ljg2LjctLjg2aDUuNThhMSAxIDAgMSAxIDAgMkg2LjV2MTAuODhhMSAxIDAgMCAxLTEgMS4xMiAxIDEgMCAwIDEtMS0xIDEgMSAwIDAgMS0xIDEgLjkzLjkzIDAgMCAxLTEtMXYtNmMtLjc4IDAtMi0uNDctMi0xdi01YTEgMSAwIDAgMSAxLTFaIiBjbGFzcz0iY2xzLTEiLz48L2c+PC9zdmc+)}.scylla-icon--testing{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTYuNSA2LjVoMTJ2MTJoLTEyeiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTQuNSA0LjVoMTZ2MTZoLTE2eiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTguNSAxMC41IDUgNSAxMS0xMiIgY2xhc3M9ImNscy0xIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--thumbs-up{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLXRodW1icy11cCI+PHBhdGggZD0iTTE0IDlWNWEzIDMgMCAwIDAtMy0zbC00IDl2MTFoMTEuMjhhMiAyIDAgMCAwIDItMS43bDEuMzgtOWEyIDIgMCAwIDAtMi0yLjN6TTcgMjJINGEyIDIgMCAwIDEtMi0ydi03YTIgMiAwIDAgMSAyLTJoMyIvPjwvc3ZnPg==)}.scylla-icon--thumbs-down{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLXRodW1icy1kb3duIj48cGF0aCBkPSJNMTAgMTV2NGEzIDMgMCAwIDAgMyAzbDQtOVYySDUuNzJhMiAyIDAgMCAwLTIgMS43bC0xLjM4IDlhMiAyIDAgMCAwIDIgMi4zem03LTEzaDIuNjdBMi4zMSAyLjMxIDAgMCAxIDIyIDR2N2EyLjMxIDIuMzEgMCAwIDEtMi4zMyAySDE3Ii8+PC9zdmc+)}.scylla-icon--tip{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTEyIDI0QzUuNCAyNCAwIDE4LjYgMCAxMlM1LjQgMCAxMiAwczEyIDUuNCAxMiAxMi01LjQgMTItMTIgMTJabTAtMjJDNi41IDIgMiA2LjUgMiAxMnM0LjUgMTAgMTAgMTAgMTAtNC41IDEwLTEwUzE3LjUgMiAxMiAyWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMSAxNmMtLjMgMC0uNS0uMS0uNy0uM2wtMy0zYy0uNC0uNC0uNC0xIDAtMS40LjQtLjQgMS0uNCAxLjQgMGwzIDNjLjQuNC40IDEgMCAxLjQtLjIuMi0uNC4zLS43LjNaIi8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTExIDE2Yy0uMyAwLS41LS4xLS43LS4zLS40LS40LS40LTEgMC0xLjRsNi02Yy40LS40IDEtLjQgMS40IDAgLjQuNC40IDEgMCAxLjRsLTYgNmMtLjIuMi0uNC4zLS43LjNaIi8+PC9zdmc+)}.scylla-icon--training{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfMiIgZGF0YS1uYW1lPSJDYWxxdWUgMiI+PHBhdGggZD0iTTE3LjUgMTUuNUguNXYtMTNoMThNNS41IDI1bDQtNC4zIDQgNC4zIiBjbGFzcz0iY2xzLTEiLz48Y2lyY2xlIGN4PSIyMSIgY3k9IjQiIHI9IjIuNSIgc3R5bGU9InN0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6bm9uZTtzdHJva2U6Z3JheSIvPjxwYXRoIGQ9Ik0yMy40MSA3LjVoLTEuNTJMMjEgOWwtLjktMS41SDEzQTEuOCAxLjggMCAwIDAgMTEuNSA5YTEuOCAxLjggMCAwIDAgMS41IDEuNWg0LjV2MTMuMjRBMS40MSAxLjQxIDAgMCAwIDE5IDI1YTEuNDIgMS40MiAwIDAgMCAxLjUtMS4yMiAxLjUzIDEuNTMgMCAwIDAgMyAwdi03LjExYTEuMTEgMS4xMSAwIDAgMCAxLjA5LTEuMThWOC42N2ExLjE4IDEuMTggMCAwIDAtMS4xOC0xLjE3Wk05LjUgMTUuNDR2NS4zOCIgY2xhc3M9ImNscy0xIi8+PC9nPjwvc3ZnPg==)}.collapsible-button .side-nav__content .toctree-checkbox:checked~label i,.collapsible-button .side-nav__content i,.scylla-icon--triangle-down,.side-nav__content .collapsible-button i,.side-nav__content .scylla-icon--expand,.side-nav__content .toctree-checkbox:checked~label .collapsible-button i,.side-nav__content .toctree-checkbox:checked~label .scylla-icon--expand{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSI1IiBmaWxsPSJub25lIj48cGF0aCBmaWxsPSIjM0EyRDU1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Im0wIDAgNSA1IDUtNUgwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.scylla-icon--university{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibTEuNSA4LjUgMTEtNCAxMSA0djNsLTExIDQtMTEtNHYtM3oiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik01LjUgMTIuNXY1YTEyLjQ2IDEyLjQ2IDAgMCAwIDcgMiAxMS4yIDExLjIgMCAwIDAgNy0ydi01IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtMTMuNSA5LjUgOCAxLjIzdjguNzdNMjIuNSAxNi41djMiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--users-blog{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTIzLjUgMi41aC0yMnYxNmgxM3Y0LjE3bDQuMDQtNC4xNyA0Ljk2LS4wNFYyLjV6IiBzdHlsZT0ic3Ryb2tlLXdpZHRoOi45OHB4O2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQiLz48cGF0aCBkPSJNMTAuODUgOEExMC4zOCAxMC4zOCAwIDAgMSAxMSA5LjVjMCAyLjQ3LTEuMjEgNC0zIDRzLTMuNS0yLTMuNS00LjVhNC4xOCA0LjE4IDAgMCAxIDAtMSIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTUuMiA1LjA3YTMuMjIgMy4yMiAwIDAgMSAyLjUtMSAzLjE2IDMuMTYgMCAwIDEgMi40IDEgNi4yMiA2LjIyIDAgMCAxIDEuMyAzLjgxLjc0Ljc0IDAgMCAwLS40MiAwYzAtLjI0IDAtLjQ0LS4wNS0uNjZoMEEzIDMgMCAwIDEgMTAgNi45di0uMjRsLS4yMS4xMkE5LjYyIDkuNjIgMCAwIDEgNC43MyA4YS4yNS4yNSAwIDAgMC0uMjIuMDljLS4xMy4xNC0uMDkuMzcgMCAuNjF2LjE4YS44NS44NSAwIDAgMC0uMzIgMEE1LjM3IDUuMzcgMCAwIDEgNS4yIDUuMDdaTTQuNTEgOC45M2MtLjM1IDAtLjU3LjA1LS42MS40NGExLjE3IDEuMTcgMCAwIDAgLjczIDEuM00xMSA4LjkzYy4zNiAwIC41Ny4wNS42Mi40NGExLjE3IDEuMTcgMCAwIDEtLjc0IDEuM002LjMxIDE0LjEzdi0uODRNOS4yNSAxMy4xOXYuOTRNMi40MiAxOGMuMTMtMS4xNS41OC0yLjUyIDEuNTgtM2ExNC43MSAxNC43MSAwIDAgMSAyLjMxLS44Mk0xMy41IDE4Yy0uMTMtMS4xNS0uNTEtMi41Mi0xLjUtM3MtMi41LTEtMi41LTEiIGNsYXNzPSJjbHMtMiIvPjxwYXRoIGQ9Ik05LjM0IDE0LjIyYTIuMjMgMi4yMyAwIDAgMS0xLjU2LjYxIDIuMzIgMi4zMiAwIDAgMS0xLjU1LS41OU0yMS41IDYuNWgtN00yMS41IDkuNWgtN00xOC41IDEyLjVoLTQiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.admonition.caution .admonition-title:before,.admonition.warning .admonition-title:before,.scylla-icon--warning{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PG1hc2sgaWQ9ImEiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyMSIgeD0iMCIgeT0iMSIgbWFzay10eXBlPSJhbHBoYSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZmlsbD0iIzA2MTkzOCIgZD0iTTMuNSAyMmMtLjUgMC0xLS4xLTEuNS0uNEMuNiAyMC44LjEgMTguOS45IDE3LjVMOS40IDMuM2MuMy0uNC42LS44IDEtMSAuNy0uNCAxLjUtLjUgMi4zLS4zLjguMiAxLjQuNyAxLjkgMS40TDIzIDE3LjVjLjMuNS40IDEgLjQgMS41IDAgLjgtLjMgMS42LS45IDIuMS0uNS42LTEuMi45LTIgLjloLTE3Wm03LjYtMTcuNkwyLjcgMTguNWMtLjMuNS0uMSAxLjEuNCAxLjQuMS4xLjMuMS40LjFoMTYuOWMuMyAwIC41LS4xLjctLjMuMi0uMi4zLS40LjMtLjcgMC0uMiAwLS4zLS4xLS41TDEyLjkgNC40Yy0uMy0uNS0uOS0uNi0xLjQtLjQtLjIuMS0uMy4yLS40LjRaIi8+PHBhdGggZmlsbD0iIzA2MTkzOCIgZD0iTTEyIDE0Yy0uNiAwLTEtLjQtMS0xVjljMC0uNi40LTEgMS0xczEgLjQgMSAxdjRjMCAuNi0uNCAxLTEgMVpNMTIgMThjLS4zIDAtLjUtLjEtLjctLjMtLjItLjItLjMtLjQtLjMtLjcgMC0uMSAwLS4zLjEtLjQuMS0uMS4xLS4yLjItLjMuMS0uMS4yLS4yLjMtLjIuMi0uMS40LS4xLjYtLjEuMSAwIC4xIDAgLjIuMS4xIDAgLjEgMCAuMi4xIDAgMCAuMS4xLjIuMS4xLjEuMi4yLjIuMyAwIC4xLjEuMy4xLjQgMCAuMy0uMS41LS4zLjctLjMuMi0uNS4zLS44LjNaIi8+PC9tYXNrPjxnIG1hc2s9InVybCgjYSkiPjxwYXRoIGZpbGw9IiMwNjE5MzgiIGQ9Ik0wIDBoMjR2MjRIMHoiLz48L2c+PC9zdmc+)}.scylla-icon--webinars{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTEuNSA1LjVoMjJ2MTRoLTIyeiIgc3R5bGU9InN0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6bm9uZTtzdHJva2U6Z3JheSIvPjxwYXRoIGQ9Ik05LjQ3IDIwLjV2MS44OE0xNS41IDIwLjV2Mk02LjUgMjIuNWgxMiIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0ibTkgOSA3LjUgMy41M0w5IDE2Vjl6IiBzdHlsZT0iZmlsbDpncmF5Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--whitepapers{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTggOWg4djJIOHoiIHN0eWxlPSJmaWxsOmdyYXkiLz48cGF0aCBkPSJNMTQuMDYgMS41IDMuNSAxLjUyVjIzLjVoMTdWN2wtNi40NC01LjV6IiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMTQuMzIgMS40MnYzLjM3YTIuMDYgMi4wNiAwIDAgMCAyLjA4IDIuMWgzLjY3IiBzdHlsZT0ic3Ryb2tlLW1pdGVybGltaXQ6MTA7ZmlsbDpub25lO3N0cm9rZTpncmF5Ii8+PHBhdGggZD0iTTYuNSAxOS41aDRNMTMuNSAxOS41aDRNNi41IDE2LjVoNE0xMy41IDE2LjVoNE02LjUgMTMuNWg0TTEzLjUgMTMuNWg0IiBjbGFzcz0iY2xzLTIiLz48L2c+PC9zdmc+)}.scylla-icon--workshop{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTojNGQ0ZDRkfS5jbHMtMXtzdHJva2UtbWl0ZXJsaW1pdDoxMH0uY2xzLTJ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTEuNSA1LjVoMjJ2MTRoLTIyeiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTkuNSAxOS41LS4wMyAyLjg4TTE1LjUgMTkuNXYzTTYuNSAyMi41aDEyIiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJtNCA4IDIgOCAuOTctMy45NUwxMSAxMiA0IDh6IiBzdHlsZT0iZmlsbDojNGQ0ZDRkIi8+PHBhdGggZD0ibTYuNDcgMTEuMzQgMy4zNyA0LjI4IiBjbGFzcz0iY2xzLTEiLz48L2c+PC9zdmc+)}.button{border:1px solid #3a2d55;border-radius:4px;display:inline;font-size:14px;letter-spacing:1px;line-height:21px;margin:0;padding:12px 14px}.button,.button:focus,.button:hover{background:transparent;color:#3a2d55}.button:focus,.button:hover{text-decoration:none}.button--reverse{background:#fff;border:0}.button--reverse:focus,.button--reverse:hover{background:#fff}.tooltip{background-color:rgba(0,0,0,.56);border-radius:4px;font-size:12px;padding:6px}.tooltip:before,.tooltip:empty{display:none!important}.has-tip{border:0;cursor:pointer}.scylla-dropdown{color:#23263b;font-size:14px;line-height:20px}.scylla-dropdown a,.scylla-dropdown a:focus,.scylla-dropdown a:hover{color:#23263b!important;padding:0!important}.scylla-dropdown__item{font-size:16px;padding:15px}.scylla-dropdown__title{align-items:center;display:flex!important;position:static!important}.scylla-dropdown__title:after{display:none!important}.scylla-dropdown__title .chevron{min-height:5px;width:10px}.scylla-dropdown__content{background:#fff;border:0;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);font-size:16px;list-style:none;margin-top:15px;overflow:hidden;padding:16px 0;width:max-content}.scylla-dropdown__content li{padding:7px 16px}.scylla-dropdown__content .contents.local>ul>li a:before,.scylla-dropdown__content .secondary-side-nav__content li a:before,.scylla-dropdown__content li .admonition-title:before,.scylla-dropdown__content li .scylla-icon,.secondary-side-nav__content .scylla-dropdown__content li a:before{margin-right:10px}.enlarge-image{cursor:zoom-in}.enlarge-image-reveal{background:transparent;border:none;cursor:zoom-out;padding:0;text-align:center;width:fit-content}.enlarge-image-reveal img{background-color:#fff;padding:15px}.header{background-color:#fff;box-shadow:0 2px 22px rgba(74,93,166,.15);justify-content:space-between;padding:12.75px 0;position:fixed;width:100%;z-index:99}.header,.header-logo{align-items:center;display:flex}.header-logo{margin-left:20px;width:auto}.header-logo__img{width:110px}.header-logo__bar{background-color:#3a2d55;border-left:1px solid #3a2d55;height:11.56px;margin:0 7.5px;width:0}.header-logo__text{color:#3a2d55;font-size:10.11px;letter-spacing:.722408px;line-height:12px;text-transform:uppercase}.header-navigation{display:none}.header-button{display:none;margin-left:15px;text-transform:uppercase}.header-search-box{display:none;margin-right:20px;width:200px}.scylla-dropdown--header .scylla-dropdown__item{font-size:14px}.scylla-dropdown--header .scylla-dropdown__title{text-transform:uppercase}.scylla-dropdown--header .scylla-dropdown__title .chevron{margin-left:10px}.contents.local>ul>li .scylla-dropdown--header .scylla-dropdown__content a:before,.scylla-dropdown--header .scylla-dropdown__content .admonition-title:before,.scylla-dropdown--header .scylla-dropdown__content .contents.local>ul>li a:before,.scylla-dropdown--header .scylla-dropdown__content .scylla-icon,.scylla-dropdown--header .scylla-dropdown__content .secondary-side-nav__content li a:before,.secondary-side-nav__content li .scylla-dropdown--header .scylla-dropdown__content a:before{min-height:20px;width:20px}@media screen and (min-width:1024px){.header{padding:18px 0}.header-logo__img{width:152px}.header-logo__bar{height:16px;margin:0 10px}.header-logo__text{font-size:14px;letter-spacing:.722408px;line-height:12px;text-transform:uppercase}.header-navigation{align-items:center;display:flex;justify-content:center}.header-search-box{display:block}}@media screen and (min-width:1200px){.header-logo{margin-left:30px;width:357px}.header-search-box{margin-right:30px;max-width:20%;width:318px}.header-button{display:block}}.side-nav{background:#fff;display:none;height:100vh;left:0;line-height:24px;max-height:calc(100vh - 50px);overflow-y:auto;padding:20px 20px 0;position:fixed;top:50px;width:100%;z-index:100}.side-nav__title{font-weight:700;margin-bottom:20px}.side-nav__content{max-width:90%;overflow-wrap:break-word}.side-nav__content label,.side-nav__content label i{margin:0;padding:0}.side-nav__content label{font-size:inherit;line-height:1;margin-left:5px;max-height:5px}.collapsible-button .side-nav__content i,.side-nav__content .collapsible-button i,.side-nav__content .scylla-icon--expand{height:5px;vertical-align:top;width:10px}.side-nav__content .toctree-checkbox{display:none;position:absolute;right:20px}.side-nav__content .toctree-checkbox~ul{display:none;margin-right:20px}.side-nav__content .toctree-checkbox:checked~ul{display:block}.side-nav__content ul{margin:0}.side-nav__content a{color:#23263b}.side-nav__content a:hover{color:#3c4fe0;font-weight:400}.side-nav__content li{list-style:none;padding:0 0 24px}.side-nav__content li.has-children{align-items:center;display:flex;flex-wrap:wrap}.side-nav__content li.has-children>a{max-width:calc(100% - 15px)}.side-nav__content li.has-children.current{padding-bottom:20px}.side-nav__content li.has-children:hover>a{color:#3c4fe0}.side-nav__content li.has-children:hover>.toctree-checkbox~label i{filter:invert(38%) sepia(71%) saturate(6789%) hue-rotate(231deg) brightness(90%) contrast(95%)}.side-nav__content li.current-page>a{color:#3c4fe0}.side-nav__content li.current-page>.toctree-checkbox:checked~label i{filter:invert(38%) sepia(71%) saturate(6789%) hue-rotate(231deg) brightness(90%) contrast(95%)}.side-nav__content li ul{margin-top:18px;width:100%}.side-nav__content li ul li{border-left:1px solid #3c4fe0;padding:4px 0 4px 13px}.side-nav__content li ul ul{margin-left:0}.side-nav__content li .label{display:none}.side-nav__versions{max-width:90%}.side-nav__search,.side-nav__versions .dropdown{margin-bottom:20px}.collapsible-button{background:#fff;background-color:#fff;border:0;border-radius:8px;border-radius:50%;bottom:10px;box-shadow:0 4px 25px rgba(0,0,0,.15);cursor:pointer;display:none;font-size:0;left:300px;overflow:hidden;padding:13.5px;position:fixed}.collapsible-button i{height:16px;margin:0;width:16px}.side-nav--collapsed .collapsible-button{border-radius:0 20px 20px 0;left:-10px}.side-nav--collapsed .collapsible-button i{transform:rotate(180deg)}.layout--has-banner .side-nav{max-height:calc(100vh - 92.5px)}@media screen and (min-width:1024px){.side-nav{background-color:#f6f8ff;display:block;height:100%;left:auto;max-height:100vh;max-height:calc(100vh - 80px);padding:30px 40px;top:80px;width:286px;z-index:25}.side-nav__content{max-width:100%;padding-bottom:180px}.side-nav__search{display:none}.side-nav__versions{max-width:100%}.toctree-checkbox{right:40px}.layout--has-banner .side-nav{max-height:calc(100vh - 150px)}}@media screen and (min-width:1200px){.side-nav{width:357px}.side-nav--collapsed{background-color:transparent;padding-left:0;padding-right:0;width:126px}.side-nav--collapsed .side-nav-content{display:none}.collapsible-button{display:block}}.side-nav-toggle{cursor:pointer;display:block;margin-right:20px;position:relative;z-index:300}@media screen and (min-width:1024px){.side-nav-toggle{display:none}}.secondary-side-nav{display:none;height:100%;line-height:24px;padding:20px;width:100%}.secondary-side-nav__content{overflow-wrap:break-word}.secondary-side-nav__content ul{list-style:none;margin:0}.secondary-side-nav__content li{border-bottom:1px solid rgba(90,94,154,.1);display:none;padding:10px 0;word-break:break-word}.secondary-side-nav__content li:last-child{border:0}.secondary-side-nav__content li .label{display:none}.secondary-side-nav__content li a{align-items:baseline;color:#b3bac5;display:flex;font-size:14px}.secondary-side-nav__content li a:before{content:"";filter:invert(40%) sepia(11%) saturate(2157%) hue-rotate(198deg) brightness(89%) contrast(87%)!important;flex-shrink:0;margin-right:10px;min-height:10px;opacity:.5;width:6px}.secondary-side-nav__content li a.current,.secondary-side-nav__content li a:hover{color:#23263b;font-weight:400}.secondary-side-nav__content li a.current:before,.secondary-side-nav__content li a:hover:before{filter:brightness(0);opacity:1}.secondary-side-nav__content li a.current{font-weight:700}.secondary-side-nav__content>ul>li>ul>li{display:block}.secondary-side-nav__content>ul>li{border:0;display:block}.secondary-side-nav__content>ul>li>a{display:none}@media screen and (min-width:1200px){.secondary-side-nav{display:block;max-height:100vh;max-height:calc(100vh - 80px);overflow-y:auto;padding:60px 60px 60px 20px;position:fixed;top:80px;width:286px}.secondary-side-nav__content{padding-bottom:180px}.layout--has-banner .secondary-side-nav{max-height:calc(100vh - 150px)}}.layout{display:flex}.pre-content{align-items:center;display:flex;justify-content:space-between;margin-bottom:20px}.content{margin-top:50px;max-width:1440px;overflow-wrap:break-word;padding:20px;width:100%}.content .line-block,.content p{line-height:28px;margin-bottom:20px}.content ul{list-style:none}.content ul li:before{color:#b3bac5;content:"•";float:left;font-family:FontAwesome;font-size:20px;font-weight:700;margin-left:-1em;margin-top:-2px;width:1em}.content ul ul{list-style:circle}.content ul ul li:before{content:""}.content ol ol{list-style:lower-latin}.content img{margin-bottom:30px}.content .inline-icon.fa-check{color:#42c4e6}.layout--full-width .content{max-width:100%;padding:0;width:100%}.layout--full-width .content .hero-wrapper,.layout--full-width .content .topics-grid{max-width:1190px}.layout--full-width .content.content--collapsed,.layout--full-width:not(.layout--sidebar) .content{margin-left:0}.landing__content{padding:0 16px}@media screen and (min-width:1024px){.content{margin-left:286px;margin-top:80px;min-height:calc(100vh - 260px);padding-bottom:100px;width:calc(100% - 286px)}}@media screen and (min-width:1200px){.content{margin-left:357px;padding:60px 40px 40px;width:calc(100% - 643px)}.content--collapsed{margin-left:126px;width:calc(100% - 412px)}.pre-content{margin-bottom:10px}.landing__content{padding:0 60px}.landing--floating .landing__content{position:relative;top:-70px}}.contents.local>ul{margin-bottom:30px;margin-left:0}.contents.local>ul>li{border-bottom:1px solid rgba(90,94,154,.1);padding:10px 0;word-break:break-word}.contents.local>ul>li:before{content:""}.contents.local>ul>li:last-child{border:0}.contents.local>ul>li ul{display:none}.contents.local>ul>li p{margin:0}.contents.local>ul>li a{font-size:14px}.contents.local>ul>li a:before{content:"";filter:invert(40%) sepia(11%) saturate(2157%) hue-rotate(198deg) brightness(89%) contrast(87%)!important;margin-right:10px;min-height:10px;opacity:.5;width:10px}.contents.local>ul>li a.current:before,.contents.local>ul>li a:hover:before{filter:brightness(0);opacity:1}.topic-title{color:rgba(35,38,59,.75);font-size:10px;letter-spacing:1.5px;margin-bottom:0;text-transform:uppercase}.notice{margin-top:40px}.footer{background-color:#fff;box-shadow:0 -4px 10px hsla(0,0%,82%,.25);padding:30px 0;position:relative;width:100%;z-index:50}.footer-group{margin:0 auto;max-width:1030px;padding:0 20px}.footer-top{align-items:center;border-bottom:1px solid rgba(0,0,0,.1);display:flex;flex-wrap:wrap;justify-content:space-between;padding-bottom:8px;text-align:center}.footer-logo{margin-bottom:30px;width:100%}.footer-logo img{float:left;height:36px}.footer-links{text-align:left}.footer-links__link{color:#333;font-size:12px;font-weight:500;letter-spacing:2.4px;margin-right:16px;text-transform:uppercase}.footer-actions{align-items:center;display:flex;justify-content:space-between;width:90px}.footer-actions__link{color:#000}.footer-actions__link img{height:23px}.footer-bottom{color:#979797;display:flex;flex-wrap:wrap;font-size:12px;font-style:normal;font-weight:400;justify-content:center;letter-spacing:1.4px;line-height:23px;padding:20px 0 10px;text-align:center;text-transform:uppercase}@media screen and (max-width:510px){.footer-links{margin-bottom:20px}}@media screen and (min-width:1024px){.footer{padding:30px 0}.footer-group{padding:0}.footer-top{padding-bottom:30px}.footer-logo{margin:0;width:auto}.footer-links{padding:0 40px}.footer-links__link{font-size:14px;margin-right:28px}.footer-actions{width:110px}.footer-actions__link img{height:28px}.footer-bottom .footer-bottom__copyright,.footer-bottom .footer-bottom__last-updated,.footer-bottom .footer-bottom__version{padding:0 10px}.footer-bottom .footer-bottom__copyright{border-left:none}}.not-found{background-color:#f6f8ff;height:100%;overflow:hidden}.not-found__icon{display:block;margin:40px auto;max-width:300px}.not-found__text{text-align:center}.not-found__text h1{font-size:60px;line-height:1}.not-found__text p{margin:30px 0;width:100%}.not-found__button{text-transform:uppercase}.admonition{border-radius:4px;box-shadow:0 4px 4px rgba(0,0,0,.12);color:rgba(0,0,0,.56);font-size:14px;line-height:20px;margin-bottom:30px;overflow:auto;padding:20px 20px 20px 52px;position:relative}.admonition:before{bottom:0;content:" ";left:0;position:absolute;right:0;top:0;z-index:-1}.admonition-title{color:#23263b;left:-32px;position:relative}.admonition-title:before{content:"";margin-right:8px;min-height:24px;width:24px}.admonition p{margin-bottom:0!important}.admonition.tip{border:1px solid #43a047}.admonition.tip:before{border-left:8px solid rgba(67,160,71,.4)}.admonition.tip .admonition-title:before{filter:invert(47%) sepia(11%) saturate(2286%) hue-rotate(73deg) brightness(109%) contrast(88%)}.admonition.note{border:1px solid #1976d2}.admonition.note:before{border-left:8px solid rgba(25,118,210,.4)}.admonition.note .admonition-title:before{filter:invert(44%) sepia(55%) saturate(2310%) hue-rotate(191deg) brightness(81%) contrast(103%)}.admonition.caution{border:1px solid #ffab00}.admonition.caution:before{border-left:8px solid rgba(255,171,0,.4)}.admonition.caution .admonition-title:before{filter:invert(77%) sepia(56%) saturate(3332%) hue-rotate(357deg) brightness(98%) contrast(108%)}.admonition.warning{border:1px solid #e74c3c}.admonition.warning:before{border-left:8px solid rgba(231,76,60,.4)}.admonition.warning .admonition-title:before{filter:invert(41%) sepia(42%) saturate(6427%) hue-rotate(343deg) brightness(99%) contrast(83%)}.breadcrumbs{margin-bottom:0;text-transform:uppercase}.breadcrumbs .bread__item,.breadcrumbs .bread__item:not(.bread__item--last):after,.breadcrumbs a{color:#23263b;font-size:12px;font-weight:400;letter-spacing:1.5px;line-height:2;margin:0;padding:0}.breadcrumbs .bread__item:before{display:none}.breadcrumbs .bread__item:not(.bread__item--last):after{content:"/";margin:0 5px;opacity:1;position:relative}.breadcrumbs .bread__highlight{color:#3c4fe0}.breadcrumbs .bread__highlight:hover{font-weight:700;text-decoration:none}code{background-color:#f7f8f9;border:none;border-radius:4px;color:#23263b;font-size:14px}code.download{background:none;color:#23263b}.highlight{background:transparent!important}.highlight pre{background-color:#f7f8f9;border-radius:8px;color:#23263b;font-size:14px;line-height:26px;margin-bottom:30px;overflow:auto;padding:16px}.highlight a.copybtn{right:1em;top:1em}.highlighttable{background-color:#f7f8f9;border-radius:16px;box-shadow:none}.highlighttable tbody{background-color:transparent;border:0}.highlighttable tbody td{padding:15px!important}.highlighttable tbody tr{border-top:none}.highlighttable .linenos{background-color:#f7f8f9;color:#5a7184;width:50px}.highlighttable .linenos span{line-height:26px}.highlighttable .highlight pre{background-color:transparent;margin:0;padding:0}.highlighttable .highlight a.copybtn{right:.2em;top:.2em}.hide-copy-button .copybtn{display:none}.sphinx_collapse__label{display:flex!important;flex-direction:row-reverse;font-size:medium;font-weight:700;justify-content:flex-end;margin-left:0!important}.sphinx_collapse__icon{margin-left:5px;margin-right:0}.sphinx_collapse__input:checked~.sphinx_collapse__label,.sphinx_collapse__label:hover{color:#3c4fe0}.sphinx_collapse__input:checked~.sphinx_collapse__label .sphinx_collapse__icon,.sphinx_collapse__label:hover .sphinx_collapse__icon{border-top-color:#3c4fe0}.sphinx_collapse__content{margin-top:10px}.contribute{margin:0 0 20px}.contribute__item{font-size:14px;list-style:none;padding-bottom:10px}.contribute__item .icon{margin-right:5px}.content-navigation{display:flex;justify-content:space-between;margin-top:40px}.navigation{max-width:50%;word-break:break-word}.navigation,.navigation__link{display:flex}.navigation__title{word-wrap:break-word;color:#23263b;font-size:12px;font-weight:500;letter-spacing:1.5px;line-height:24px;text-transform:uppercase}.navigation__title .colored{color:#42c4e6}.navigation__button{background:#fff;background-color:#fff;border:0;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);cursor:pointer;display:none;font-size:0;height:fit-content;overflow:hidden;padding:13.5px 16.5px}.navigation__button i{height:16px;margin:0;width:10px}.navigation--prev .navigation__title{margin-left:15px}.navigation--next .navigation__title{margin-right:15px;text-align:right}@media screen and (min-width:1200px){.navigation__title{display:inline-block}.navigation__button{display:block}.navigation--next .navigation__title{text-align:left}}.scylla-dropdown--versions .scylla-dropdown__item{background:#fff;border-radius:8px;box-shadow:0 28px 32px rgba(0,0,0,.06);width:100%}.scylla-dropdown--versions .scylla-dropdown__title{align-items:center;display:flex;justify-content:space-between}.scylla-dropdown--versions .scylla-dropdown__title .chevron{min-height:12px;transform:rotate(90deg);width:8px}@media screen and (min-width:1024px){.scylla-dropdown--versions .scylla-dropdown__item{box-shadow:none}}.feedback-container{font-size:16px;margin-top:40px;text-align:left}.feedback-container__title{font-weight:700;margin-bottom:5px!important}.feedback-container__button{background:#fff;border:0;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);cursor:pointer;margin:4px;overflow:hidden;padding:8px}.feedback-container__button.active{border:1px solid #3c4fe0}.feedback-container__icon{height:20px;width:20px}.feedback-container__message{font-size:16px;margin-top:10px}.hero{background:#f6f8ff;margin-bottom:30px;overflow:hidden;padding:30px 16px;text-align:left}.hero__title{font-size:28px;font-weight:500;line-height:38px;margin-bottom:14px;max-width:229px}.hero__text{font-size:16px;line-height:26px;max-width:343px}.hero__text a{border-bottom:1px dotted #23263b;color:#23263b}.hero__text p{margin-bottom:0!important}.hero__img{position:absolute;right:-18px;top:20px}.hero__img img{margin-bottom:0!important;width:124px}.hero__button{margin-top:20px;text-transform:uppercase}.hero__button .icon{margin-right:5px}.hero__search-box{box-shadow:0 4px 25px rgba(0,0,0,.02);margin-top:20px}.hero-wrapper{align-items:center;display:flex;justify-content:space-between;margin:0 auto;position:relative}@media screen and (min-width:640px){.hero{padding:60px 16px}.hero__title{font-size:32px;line-height:42px;max-width:482px}.hero__text{font-size:18px;line-height:26px;max-width:482px}.hero__img{display:block;position:static}.hero__img img{height:100%;width:295px}.hero .hero-wrapper{flex-direction:row-reverse}.hero .landing--floating .hero{padding:30px 16px 100px}}@media screen and (min-width:1024px){.hero{padding:60px}}.label{background-color:#23263b;border:0;border-radius:4px;color:#fff;font-size:inherit}.label--note{background-color:#1976d2}.label--tip{background-color:#43a047}.label--caution{background-color:#ffab00}.label--warning{background-color:#e74c3c}.last-updated{color:#4458a3;font-size:12px;letter-spacing:1.5px;margin:10px 0;text-transform:uppercase}.last-updated__icon{font-size:14px}@media screen and (min-width:1024px){.last-updated{float:right;margin:0}}.panel{border:0;border-radius:4px;margin-bottom:30px}.promo-banner{background-color:#4458a3;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDQwIiBoZWlnaHQ9IjcwIiBmaWxsPSJub25lIj48bWFzayBpZD0iYSIgd2lkdGg9IjE0NDAiIGhlaWdodD0iNzAiIHg9IjAiIHk9IjAiIG1hc2stdHlwZT0iYWxwaGEiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiPjxwYXRoIGZpbGw9IiM0NDU4QTMiIGQ9Ik0wIDBoMTQ0MHY3MEgweiIvPjwvbWFzaz48ZyBmaWxsPSIjNTA2NEFFIiBtYXNrPSJ1cmwoI2EpIj48cGF0aCBkPSJNLTE5MyAyMDEuODg0IDEuNS0xMzUgMzU3LjQzNiA3MC41bC0xOTQuNSAzMzYuODg0ek0xMDkyLjkyLTM4LjAwOSA5NzIuODAzLTI0Ni4wNTcgNDAyLjk5NiA4Mi45MiA1MjMuMTEzIDI5MC45N3oiLz48cGF0aCBkPSJtMTAzOC0zOC4wMDkgMTIwLjExNy0yMDguMDQ5IDU2OS44MDcgMzI4Ljk3OS0xMjAuMTE3IDIwOC4wNDl6Ii8+PC9nPjwvc3ZnPg==);background-position:50%;background-repeat:no-repeat;background-size:cover;display:none;overflow:hidden;position:fixed;top:0;width:100%;z-index:900}.promo-banner__icon{margin-right:15px}.promo-banner__icon img{height:40px}.promo-banner__title{color:#fff;font-size:12px;line-height:16px;margin-right:15px}.promo-banner__button{background:#fff;border-radius:4px;font-size:12px;min-width:max-content;padding:5px}.promo-banner__close{display:none;position:absolute;right:16px;top:16px}.contents.local>ul>li .promo-banner__close a:before,.promo-banner__close .admonition-title:before,.promo-banner__close .contents.local>ul>li a:before,.promo-banner__close .scylla-icon,.promo-banner__close .secondary-side-nav__content li a:before,.secondary-side-nav__content li .promo-banner__close a:before{filter:brightness(100%);height:34px;width:34px}.promo-banner__close:hover{cursor:pointer;filter:opacity(.8)}.promo-banner-wrapper{align-items:center;display:flex;justify-content:center;padding:5.85px 20px}@media(min-width:1024px){.promo-banner__title{font-size:18px;line-height:23px}.promo-banner__button{font-size:14px;padding:8.5px}.promo-banner__close{display:block}.promo-banner-wrapper{flex-direction:unset;padding:16px}}.custom-scroll-bar::-webkit-scrollbar{background-color:transparent;width:5px}.custom-scroll-bar::-webkit-scrollbar-thumb{background-color:#b3bac5;-webkit-border-radius:8px;border-radius:8px}.search-box{background:#f7f8f9;border-radius:4px;display:flex;padding:10px 15px}.search-box--hero{background-color:#fff;padding:12px 14px}.search-box:before{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTEwLjUgMThhNy41IDcuNSAwIDEgMCAwLTE1IDcuNSA3LjUgMCAwIDAgMCAxNVpNMjEgMjFsLTUuMi01LjIiLz48L3N2Zz4=);background-repeat:no-repeat;background-size:contain;content:"";display:inline-block;filter:brightness(0);margin-top:2px;min-height:18px;min-width:18px;vertical-align:middle;width:20px}.search-box .er-dummy-search,.search-box .er-dummy-search-box,.search-box .er-search-form,.search-box ci-search,.search-box input{margin:0!important;width:100%!important}.search-box input{background:transparent!important;color:rgba(80,80,80,.5)!important;font-size:14px!important;padding:0!important}.search-box input::placeholder{color:rgba(80,80,80,.5)!important;opacity:1!important}.search-box button{display:none!important}.er_search_suggestions{background:#fff;border:0;border:0!important;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);overflow:hidden}.er_search_suggestions .er-search-result-box{border-width:1px!important;padding-bottom:10px!important;padding-top:10px!important}.er_search_suggestions .er-search-result-box:hover{background:#f7f8f9!important}.er_search_suggestions .er_more_result_btn{cursor:pointer}.er_search_suggestions h3{font-size:16px!important}.er-search-content{padding:20px!important}#er_search_results .er-search-result-box{display:block!important;margin:10px auto 0!important;width:100%!important}#er_search_results .text,#er_search_results .title a,#er_search_results .url a{max-width:100%!important}#search-result-input-form{max-width:800px!important}#er_search_button{text-align:center}#er_clear_input{right:0!important;top:0!important}.er-facet-header{background-color:transparent!important;border:0!important;padding:0 0 8px!important}.er-facet-val{padding:5px 2px!important}.er-facet-val input{display:block!important;margin:0}#er_search_pagination{margin-top:20px!important}#er_search_pagination li.er-paginator-list.er-active{border-bottom:0!important;font-weight:700}.er-suggestion-sm .er_search_input_dummy{margin:0!important}.er-suggestion-sm .er_search_button_dummy{border:0!important}#er_gcs_mobile_model_container .er-facet-values .er-facet-val{align-items:baseline}@media screen and (min-width:640px){.er-facets{display:none;max-width:300px!important;min-width:auto!important;width:auto!important}}@media screen and (min-width:1024px){.er-suggestions{left:15px!important}}@media screen and (min-width:1200px){.er-facets{display:block;position:fixed!important}.er-facet-count{display:none}}.sphinx-tabs{margin-bottom:30px}.sphinx-tabs-tab{border-bottom:1px solid rgba(0,0,0,.56);color:rgba(0,0,0,.56);cursor:pointer;font-size:14px;font-weight:500;line-height:13px;padding:20px 25px}.sphinx-tabs-tab[aria-selected=true]{border-bottom:2px solid #2196f3;color:#2196f3;padding-bottom:19px}.sphinx-tabs-panel{margin:30px 0}.table-wrapper{border:1px solid #e0e0e0;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.25);display:block;margin-bottom:30px;max-width:100%;overflow-x:auto}table{color:#000;font-size:14px;line-height:24px;margin:0;overflow:hidden}table p{margin:0!important}table caption{background:#f6f8ff;border-bottom:1px solid #e0e0e0;color:#23263b;padding:10px 25px}table thead{background:#f6f8ff;border:0;border-bottom:1px solid #4458a3}table thead th{color:#23263b;font-size:14px;font-weight:700}table td,table thead th{padding:20px 25px}table tbody tr{background-color:transparent!important;border-top:1px solid #e0e0e0;line-height:18px}table:not(.highlighttable) tbody tr:first-child{border-top:1px solid #4458a3}table.thead-border thead .row-odd th{color:#23263b}table.thead-border thead .row-even th{font-weight:400}table.thead-border thead th{border:1px solid #e0e0e0}table.thead-border thead tr:first-child th{border-top:none}table.thead-border thead tr:last-child th{border-bottom:none}table.thead-border thead tr th:first-child{border-left:none}table.thead-border thead tr th:last-child{border-right:none}.topics-grid{display:block;margin:0 auto 30px}.topics-grid__title{color:#23263b;font-size:24px;font-weight:700;line-height:32px;margin-bottom:6px}.topics-grid__text{color:#4458a3;font-size:18px;line-height:24px}.topics-grid--scrollable .hs{-ms-overflow-style:none;display:grid;grid-auto-flow:column;overflow-x:scroll;padding:20px 10px;scrollbar-width:none}.topics-grid--scrollable .hs::-webkit-scrollbar{display:none}.topics-grid--scrollable .hs .topic-box:last-child:after{content:"";width:20px}.topic-box{align-items:stretch;display:flex}.topic-box .card{background:#fff;border:1px solid transparent;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);display:flex;flex-direction:column;font-size:18px;margin:0 auto 30px;overflow:hidden;padding:20px;position:relative}.topic-box .card:hover{border:1px solid #4458a3;color:#23263b;font-weight:400}.topic-box__title{color:#23263b;font-size:16px;font-weight:700;line-height:24px;margin-bottom:0}.topic-box__title img{bottom:0;opacity:.3;position:absolute;right:0;top:0}.topic-box__body{color:#000;display:flex;flex-direction:column;flex-grow:1;max-width:80%}.topic-box__body .container{flex-grow:1;margin:0;padding:0}.topic-box__body .line-block,.topic-box__body p{font-size:16px;line-height:19px;margin-top:10px}.topic-box__anchor{color:#42c4e6;font-size:14px;font-weight:700;line-height:24px}.topic-box__icon{display:block;font-size:50px;margin-bottom:20px}.topic-box__icon i{filter:brightness(0);min-height:50px;width:100%}.topic-box__icon img{bottom:-12px;display:none;height:140px;margin:0;opacity:.3;position:absolute;right:-5px}.topic-box--product .card{box-shadow:none;padding:20px;text-align:center}.topic-box--product .card .topic-box__title{color:#23263b;font-size:14px}.topic-box--product .card .topic-box__body{display:flex;flex-direction:column;max-width:100%}.topic-box--product .card .topic-box__body .line-block,.topic-box--product .card .topic-box__body p{font-size:12px}.topic-box--product .card .topic-box__icon img{display:inline-block;max-height:84px;opacity:1;position:static}.topic-box--product .card:hover{background:#fff;border:0;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);overflow:hidden}@media screen and (max-width:1024px){.topics-grid--scrollable .topic-box{width:280px!important}.topic-box--product:nth-last-child(-n+2) .card{margin-bottom:0}}@media screen and (min-width:1024px){.topics-grid{margin-bottom:10px}.topics-grid__text{font-size:16px}.topics-grid--scrollable .hs{display:flex;overflow-x:initial;padding:0}.topics-grid--scrollable .hs .topic-box:last-child:after{display:none}.topic-box .card{margin-bottom:60px;padding:45px 30px}.topic-box__title{font-size:20px;line-height:32px}.topic-box__body .line-block,.topic-box__body p{font-size:18px;line-height:26px}.topic-box__anchor{font-size:20px;line-height:26px}.topic-box .topic-box__icon img{display:inline-block}.topic-box--product .card{padding:20px}.topic-box--product .card .topic-box__title{font-size:18px;line-height:24px}.topic-box--product .card .topic-box__body .line-block,.topic-box--product .card .topic-box__body p{font-size:14px}.topic-box--product .card .topic-box__icon img{max-height:111px}.landing .topics-grid--products{margin-bottom:40px}} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..d06a71d7 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..7e4c114f --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/img/banner-background.svg b/_static/img/banner-background.svg new file mode 100644 index 00000000..f8520d5b --- /dev/null +++ b/_static/img/banner-background.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/_static/img/favicon-228x228.png b/_static/img/favicon-228x228.png new file mode 100644 index 00000000..f30770c7 Binary files /dev/null and b/_static/img/favicon-228x228.png differ diff --git a/_static/img/favicon-32x32.png b/_static/img/favicon-32x32.png new file mode 100644 index 00000000..aae1708f Binary files /dev/null and b/_static/img/favicon-32x32.png differ diff --git a/_static/img/favicon.ico b/_static/img/favicon.ico new file mode 100644 index 00000000..6c7484f0 Binary files /dev/null and b/_static/img/favicon.ico differ diff --git a/_static/img/icons/icon-about-team.svg b/_static/img/icons/icon-about-team.svg new file mode 100644 index 00000000..5448c7f0 --- /dev/null +++ b/_static/img/icons/icon-about-team.svg @@ -0,0 +1 @@ +icon-about-team diff --git a/_static/img/icons/icon-about-us-m.svg b/_static/img/icons/icon-about-us-m.svg new file mode 100644 index 00000000..09107d95 --- /dev/null +++ b/_static/img/icons/icon-about-us-m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/icons/icon-about-us.svg b/_static/img/icons/icon-about-us.svg new file mode 100644 index 00000000..1b1fcc83 --- /dev/null +++ b/_static/img/icons/icon-about-us.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/icons/icon-alternator.svg b/_static/img/icons/icon-alternator.svg new file mode 100644 index 00000000..7c2b4eba --- /dev/null +++ b/_static/img/icons/icon-alternator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/icons/icon-apps.svg b/_static/img/icons/icon-apps.svg new file mode 100644 index 00000000..7e936120 --- /dev/null +++ b/_static/img/icons/icon-apps.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-architecture.svg b/_static/img/icons/icon-architecture.svg new file mode 100644 index 00000000..67ebbc2f --- /dev/null +++ b/_static/img/icons/icon-architecture.svg @@ -0,0 +1 @@ +icon-architecture diff --git a/_static/img/icons/icon-benchmarks.svg b/_static/img/icons/icon-benchmarks.svg new file mode 100644 index 00000000..e1ce2c1d --- /dev/null +++ b/_static/img/icons/icon-benchmarks.svg @@ -0,0 +1 @@ +icon-benchmarks diff --git a/_static/img/icons/icon-blog.svg b/_static/img/icons/icon-blog.svg new file mode 100644 index 00000000..f4096cbf --- /dev/null +++ b/_static/img/icons/icon-blog.svg @@ -0,0 +1 @@ +icon-blog2 diff --git a/_static/img/icons/icon-careers.svg b/_static/img/icons/icon-careers.svg new file mode 100644 index 00000000..2a7c6ea0 --- /dev/null +++ b/_static/img/icons/icon-careers.svg @@ -0,0 +1 @@ +icon-careers diff --git a/_static/img/icons/icon-chevron-left.svg b/_static/img/icons/icon-chevron-left.svg new file mode 100644 index 00000000..3afa25c4 --- /dev/null +++ b/_static/img/icons/icon-chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/_static/img/icons/icon-chevron-right.svg b/_static/img/icons/icon-chevron-right.svg new file mode 100644 index 00000000..44eb829c --- /dev/null +++ b/_static/img/icons/icon-chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/_static/img/icons/icon-circe.svg b/_static/img/icons/icon-circe.svg new file mode 100644 index 00000000..875e4216 --- /dev/null +++ b/_static/img/icons/icon-circe.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-clock.svg b/_static/img/icons/icon-clock.svg new file mode 100644 index 00000000..8c924698 --- /dev/null +++ b/_static/img/icons/icon-clock.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-close.svg b/_static/img/icons/icon-close.svg new file mode 100644 index 00000000..d1162b73 --- /dev/null +++ b/_static/img/icons/icon-close.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/_static/img/icons/icon-cloud-docs.svg b/_static/img/icons/icon-cloud-docs.svg new file mode 100644 index 00000000..a9069bb6 --- /dev/null +++ b/_static/img/icons/icon-cloud-docs.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-cloud.svg b/_static/img/icons/icon-cloud.svg new file mode 100644 index 00000000..cfb2318d --- /dev/null +++ b/_static/img/icons/icon-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/icons/icon-comparison.svg b/_static/img/icons/icon-comparison.svg new file mode 100644 index 00000000..49d809a5 --- /dev/null +++ b/_static/img/icons/icon-comparison.svg @@ -0,0 +1 @@ +icon-comparison diff --git a/_static/img/icons/icon-contact-us.svg b/_static/img/icons/icon-contact-us.svg new file mode 100644 index 00000000..9df3145d --- /dev/null +++ b/_static/img/icons/icon-contact-us.svg @@ -0,0 +1 @@ +icon-contact-us diff --git a/_static/img/icons/icon-developers-blog.svg b/_static/img/icons/icon-developers-blog.svg new file mode 100644 index 00000000..ee804197 --- /dev/null +++ b/_static/img/icons/icon-developers-blog.svg @@ -0,0 +1 @@ +icon-developers-blog diff --git a/_static/img/icons/icon-docs.svg b/_static/img/icons/icon-docs.svg new file mode 100644 index 00000000..5501492f --- /dev/null +++ b/_static/img/icons/icon-docs.svg @@ -0,0 +1 @@ +icon-docs diff --git a/_static/img/icons/icon-enterprise-m.svg b/_static/img/icons/icon-enterprise-m.svg new file mode 100644 index 00000000..97be900b --- /dev/null +++ b/_static/img/icons/icon-enterprise-m.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/img/icons/icon-enterprise.svg b/_static/img/icons/icon-enterprise.svg new file mode 100644 index 00000000..ee1ac262 --- /dev/null +++ b/_static/img/icons/icon-enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/icons/icon-events.svg b/_static/img/icons/icon-events.svg new file mode 100644 index 00000000..ba5f2118 --- /dev/null +++ b/_static/img/icons/icon-events.svg @@ -0,0 +1 @@ +icon-events diff --git a/_static/img/icons/icon-exclamation.svg b/_static/img/icons/icon-exclamation.svg new file mode 100644 index 00000000..a7eb4b77 --- /dev/null +++ b/_static/img/icons/icon-exclamation.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/_static/img/icons/icon-expand.svg b/_static/img/icons/icon-expand.svg new file mode 100644 index 00000000..38065653 --- /dev/null +++ b/_static/img/icons/icon-expand.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/_static/img/icons/icon-forum.svg b/_static/img/icons/icon-forum.svg new file mode 100644 index 00000000..37a709f7 --- /dev/null +++ b/_static/img/icons/icon-forum.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-getting-started.svg b/_static/img/icons/icon-getting-started.svg new file mode 100644 index 00000000..702500be --- /dev/null +++ b/_static/img/icons/icon-getting-started.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-glossary.svg b/_static/img/icons/icon-glossary.svg new file mode 100644 index 00000000..e8329c2a --- /dev/null +++ b/_static/img/icons/icon-glossary.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-home.svg b/_static/img/icons/icon-home.svg new file mode 100644 index 00000000..f0b9c254 --- /dev/null +++ b/_static/img/icons/icon-home.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-infoworld.svg b/_static/img/icons/icon-infoworld.svg new file mode 100644 index 00000000..906e8727 --- /dev/null +++ b/_static/img/icons/icon-infoworld.svg @@ -0,0 +1 @@ +icon-infoworld diff --git a/_static/img/icons/icon-integrations.svg b/_static/img/icons/icon-integrations.svg new file mode 100644 index 00000000..1ef0920d --- /dev/null +++ b/_static/img/icons/icon-integrations.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-knowledge-base.svg b/_static/img/icons/icon-knowledge-base.svg new file mode 100644 index 00000000..88445127 --- /dev/null +++ b/_static/img/icons/icon-knowledge-base.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-less.svg b/_static/img/icons/icon-less.svg new file mode 100644 index 00000000..3094127d --- /dev/null +++ b/_static/img/icons/icon-less.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/_static/img/icons/icon-live-test.svg b/_static/img/icons/icon-live-test.svg new file mode 100644 index 00000000..dcb5916c --- /dev/null +++ b/_static/img/icons/icon-live-test.svg @@ -0,0 +1 @@ +icon-live-test diff --git a/_static/img/icons/icon-mail-list.svg b/_static/img/icons/icon-mail-list.svg new file mode 100644 index 00000000..0e6192a3 --- /dev/null +++ b/_static/img/icons/icon-mail-list.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-manager.svg b/_static/img/icons/icon-manager.svg new file mode 100644 index 00000000..02b4e425 --- /dev/null +++ b/_static/img/icons/icon-manager.svg @@ -0,0 +1 @@ +icon-manager diff --git a/_static/img/icons/icon-memory-management.svg b/_static/img/icons/icon-memory-management.svg new file mode 100644 index 00000000..e34eb450 --- /dev/null +++ b/_static/img/icons/icon-memory-management.svg @@ -0,0 +1 @@ +icon-memory-management diff --git a/_static/img/icons/icon-modeling.svg b/_static/img/icons/icon-modeling.svg new file mode 100644 index 00000000..97fa3a0e --- /dev/null +++ b/_static/img/icons/icon-modeling.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-monitoring.svg b/_static/img/icons/icon-monitoring.svg new file mode 100644 index 00000000..80b3787f --- /dev/null +++ b/_static/img/icons/icon-monitoring.svg @@ -0,0 +1 @@ +icon-monitoring diff --git a/_static/img/icons/icon-networking.svg b/_static/img/icons/icon-networking.svg new file mode 100644 index 00000000..40a3fd5f --- /dev/null +++ b/_static/img/icons/icon-networking.svg @@ -0,0 +1 @@ +icon-networking diff --git a/_static/img/icons/icon-news.svg b/_static/img/icons/icon-news.svg new file mode 100644 index 00000000..a952b599 --- /dev/null +++ b/_static/img/icons/icon-news.svg @@ -0,0 +1 @@ +icon-news diff --git a/_static/img/icons/icon-newsletter.svg b/_static/img/icons/icon-newsletter.svg new file mode 100644 index 00000000..5b8d47eb --- /dev/null +++ b/_static/img/icons/icon-newsletter.svg @@ -0,0 +1 @@ +icon-newsletter diff --git a/_static/img/icons/icon-nsql-guides.svg b/_static/img/icons/icon-nsql-guides.svg new file mode 100644 index 00000000..60ebab37 --- /dev/null +++ b/_static/img/icons/icon-nsql-guides.svg @@ -0,0 +1 @@ +icon-nsql-guides diff --git a/_static/img/icons/icon-open-source.svg b/_static/img/icons/icon-open-source.svg new file mode 100644 index 00000000..98c2ea7d --- /dev/null +++ b/_static/img/icons/icon-open-source.svg @@ -0,0 +1 @@ +icon-open-source diff --git a/_static/img/icons/icon-operator.svg b/_static/img/icons/icon-operator.svg new file mode 100644 index 00000000..bb7d8d3e --- /dev/null +++ b/_static/img/icons/icon-operator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/icons/icon-overview.svg b/_static/img/icons/icon-overview.svg new file mode 100644 index 00000000..515c1528 --- /dev/null +++ b/_static/img/icons/icon-overview.svg @@ -0,0 +1 @@ +icon-overview diff --git a/_static/img/icons/icon-partners.svg b/_static/img/icons/icon-partners.svg new file mode 100644 index 00000000..d0146fc4 --- /dev/null +++ b/_static/img/icons/icon-partners.svg @@ -0,0 +1 @@ +icon-partners diff --git a/_static/img/icons/icon-plus.svg b/_static/img/icons/icon-plus.svg new file mode 100644 index 00000000..57574350 --- /dev/null +++ b/_static/img/icons/icon-plus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/_static/img/icons/icon-pricing.svg b/_static/img/icons/icon-pricing.svg new file mode 100644 index 00000000..74b01db1 --- /dev/null +++ b/_static/img/icons/icon-pricing.svg @@ -0,0 +1 @@ +icon-pricing$ diff --git a/_static/img/icons/icon-release-notes.svg b/_static/img/icons/icon-release-notes.svg new file mode 100644 index 00000000..80c490c7 --- /dev/null +++ b/_static/img/icons/icon-release-notes.svg @@ -0,0 +1 @@ +icon-release-notes diff --git a/_static/img/icons/icon-resource-center.svg b/_static/img/icons/icon-resource-center.svg new file mode 100644 index 00000000..6e3ab08e --- /dev/null +++ b/_static/img/icons/icon-resource-center.svg @@ -0,0 +1 @@ +icon-ressource-center diff --git a/_static/img/icons/icon-roadmap.svg b/_static/img/icons/icon-roadmap.svg new file mode 100644 index 00000000..c8cbf67c --- /dev/null +++ b/_static/img/icons/icon-roadmap.svg @@ -0,0 +1 @@ +icon-roadmap-4 diff --git a/_static/img/icons/icon-search.svg b/_static/img/icons/icon-search.svg new file mode 100644 index 00000000..81aae93e --- /dev/null +++ b/_static/img/icons/icon-search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/img/icons/icon-slack.svg b/_static/img/icons/icon-slack.svg new file mode 100644 index 00000000..fc164ea1 --- /dev/null +++ b/_static/img/icons/icon-slack.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-stack-overflow.svg b/_static/img/icons/icon-stack-overflow.svg new file mode 100644 index 00000000..bebe9b82 --- /dev/null +++ b/_static/img/icons/icon-stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/img/icons/icon-summit.svg b/_static/img/icons/icon-summit.svg new file mode 100644 index 00000000..4b900bd0 --- /dev/null +++ b/_static/img/icons/icon-summit.svg @@ -0,0 +1 @@ + diff --git a/_static/img/icons/icon-support.svg b/_static/img/icons/icon-support.svg new file mode 100644 index 00000000..a4228b34 --- /dev/null +++ b/_static/img/icons/icon-support.svg @@ -0,0 +1 @@ +icon-support diff --git a/_static/img/icons/icon-tech-talks.svg b/_static/img/icons/icon-tech-talks.svg new file mode 100644 index 00000000..df42b552 --- /dev/null +++ b/_static/img/icons/icon-tech-talks.svg @@ -0,0 +1 @@ +icon-tech-talks diff --git a/_static/img/icons/icon-testing.svg b/_static/img/icons/icon-testing.svg new file mode 100644 index 00000000..2fe54efd --- /dev/null +++ b/_static/img/icons/icon-testing.svg @@ -0,0 +1 @@ +icon-testing diff --git a/_static/img/icons/icon-thumbs-down.svg b/_static/img/icons/icon-thumbs-down.svg new file mode 100644 index 00000000..3e7bcd6d --- /dev/null +++ b/_static/img/icons/icon-thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/icons/icon-thumbs-up.svg b/_static/img/icons/icon-thumbs-up.svg new file mode 100644 index 00000000..226c44d8 --- /dev/null +++ b/_static/img/icons/icon-thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/icons/icon-tip.svg b/_static/img/icons/icon-tip.svg new file mode 100644 index 00000000..bf7aa6af --- /dev/null +++ b/_static/img/icons/icon-tip.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/_static/img/icons/icon-training.svg b/_static/img/icons/icon-training.svg new file mode 100644 index 00000000..08b95a88 --- /dev/null +++ b/_static/img/icons/icon-training.svg @@ -0,0 +1 @@ +icon-training diff --git a/_static/img/icons/icon-triangle-down.svg b/_static/img/icons/icon-triangle-down.svg new file mode 100644 index 00000000..e8ae0881 --- /dev/null +++ b/_static/img/icons/icon-triangle-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/_static/img/icons/icon-university.svg b/_static/img/icons/icon-university.svg new file mode 100644 index 00000000..f7547ab9 --- /dev/null +++ b/_static/img/icons/icon-university.svg @@ -0,0 +1 @@ +icon-university diff --git a/_static/img/icons/icon-users-blog.svg b/_static/img/icons/icon-users-blog.svg new file mode 100644 index 00000000..47e56cdd --- /dev/null +++ b/_static/img/icons/icon-users-blog.svg @@ -0,0 +1 @@ +icon-users-blog diff --git a/_static/img/icons/icon-warning.svg b/_static/img/icons/icon-warning.svg new file mode 100644 index 00000000..e4b1d403 --- /dev/null +++ b/_static/img/icons/icon-warning.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/_static/img/icons/icon-webinars.svg b/_static/img/icons/icon-webinars.svg new file mode 100644 index 00000000..5e9f5cd4 --- /dev/null +++ b/_static/img/icons/icon-webinars.svg @@ -0,0 +1 @@ +icon-webinars diff --git a/_static/img/icons/icon-whitepapers.svg b/_static/img/icons/icon-whitepapers.svg new file mode 100644 index 00000000..3351e51d --- /dev/null +++ b/_static/img/icons/icon-whitepapers.svg @@ -0,0 +1 @@ +icon-whitepapers diff --git a/_static/img/icons/icon-workshop.svg b/_static/img/icons/icon-workshop.svg new file mode 100644 index 00000000..5206e58e --- /dev/null +++ b/_static/img/icons/icon-workshop.svg @@ -0,0 +1 @@ + diff --git a/_static/img/logo-docs.svg b/_static/img/logo-docs.svg new file mode 100644 index 00000000..4fff669c --- /dev/null +++ b/_static/img/logo-docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/img/logo-scylla-horizontal-RGB.svg b/_static/img/logo-scylla-horizontal-RGB.svg new file mode 100644 index 00000000..b5022d7c --- /dev/null +++ b/_static/img/logo-scylla-horizontal-RGB.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/img/mascots/404.jpg b/_static/img/mascots/404.jpg new file mode 100644 index 00000000..769fa088 Binary files /dev/null and b/_static/img/mascots/404.jpg differ diff --git a/_static/img/mascots/scylla-3monsters.png b/_static/img/mascots/scylla-3monsters.png new file mode 100644 index 00000000..7c06d016 Binary files /dev/null and b/_static/img/mascots/scylla-3monsters.png differ diff --git a/_static/img/mascots/scylla-advisor-crystal.png b/_static/img/mascots/scylla-advisor-crystal.png new file mode 100644 index 00000000..d33fddd6 Binary files /dev/null and b/_static/img/mascots/scylla-advisor-crystal.png differ diff --git a/_static/img/mascots/scylla-alternator.svg b/_static/img/mascots/scylla-alternator.svg new file mode 100644 index 00000000..0462f893 --- /dev/null +++ b/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/_static/img/mascots/scylla-care-pet-mascot.svg b/_static/img/mascots/scylla-care-pet-mascot.svg new file mode 100644 index 00000000..8bb17041 --- /dev/null +++ b/_static/img/mascots/scylla-care-pet-mascot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/img/mascots/scylla-cloud.svg b/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 00000000..a6c6a26f --- /dev/null +++ b/_static/img/mascots/scylla-cloud.svg @@ -0,0 +1 @@ +scylla-cloud diff --git a/_static/img/mascots/scylla-computer-3-monsters.png b/_static/img/mascots/scylla-computer-3-monsters.png new file mode 100644 index 00000000..d0368a70 Binary files /dev/null and b/_static/img/mascots/scylla-computer-3-monsters.png differ diff --git a/_static/img/mascots/scylla-computer-headset.png b/_static/img/mascots/scylla-computer-headset.png new file mode 100644 index 00000000..0cdadaa2 Binary files /dev/null and b/_static/img/mascots/scylla-computer-headset.png differ diff --git a/_static/img/mascots/scylla-cup-number-one.png b/_static/img/mascots/scylla-cup-number-one.png new file mode 100644 index 00000000..e889f4e3 Binary files /dev/null and b/_static/img/mascots/scylla-cup-number-one.png differ diff --git a/_static/img/mascots/scylla-docs.svg b/_static/img/mascots/scylla-docs.svg new file mode 100644 index 00000000..a5bce950 --- /dev/null +++ b/_static/img/mascots/scylla-docs.svg @@ -0,0 +1 @@ +scylla-docs diff --git a/_static/img/mascots/scylla-drivers.svg b/_static/img/mascots/scylla-drivers.svg new file mode 100644 index 00000000..6012e716 --- /dev/null +++ b/_static/img/mascots/scylla-drivers.svg @@ -0,0 +1 @@ +scylla-manager diff --git a/_static/img/mascots/scylla-enterprise.svg b/_static/img/mascots/scylla-enterprise.svg new file mode 100644 index 00000000..a1aa0b46 --- /dev/null +++ b/_static/img/mascots/scylla-enterprise.svg @@ -0,0 +1 @@ +scylla-enterprise diff --git a/_static/img/mascots/scylla-forklift-boxes.png b/_static/img/mascots/scylla-forklift-boxes.png new file mode 100644 index 00000000..f64c29e6 Binary files /dev/null and b/_static/img/mascots/scylla-forklift-boxes.png differ diff --git a/_static/img/mascots/scylla-forklift-migration.png b/_static/img/mascots/scylla-forklift-migration.png new file mode 100644 index 00000000..d2f645c6 Binary files /dev/null and b/_static/img/mascots/scylla-forklift-migration.png differ diff --git a/_static/img/mascots/scylla-gear.png b/_static/img/mascots/scylla-gear.png new file mode 100644 index 00000000..0f53b26a Binary files /dev/null and b/_static/img/mascots/scylla-gear.png differ diff --git a/_static/img/mascots/scylla-hardhat.png b/_static/img/mascots/scylla-hardhat.png new file mode 100644 index 00000000..630f2d90 Binary files /dev/null and b/_static/img/mascots/scylla-hardhat.png differ diff --git a/_static/img/mascots/scylla-headband.png b/_static/img/mascots/scylla-headband.png new file mode 100644 index 00000000..c87abe68 Binary files /dev/null and b/_static/img/mascots/scylla-headband.png differ diff --git a/_static/img/mascots/scylla-headset.png b/_static/img/mascots/scylla-headset.png new file mode 100644 index 00000000..ba52cd22 Binary files /dev/null and b/_static/img/mascots/scylla-headset.png differ diff --git a/_static/img/mascots/scylla-hearts.png b/_static/img/mascots/scylla-hearts.png new file mode 100644 index 00000000..cef08c86 Binary files /dev/null and b/_static/img/mascots/scylla-hearts.png differ diff --git a/_static/img/mascots/scylla-looking-down.png b/_static/img/mascots/scylla-looking-down.png new file mode 100644 index 00000000..75cccbfd Binary files /dev/null and b/_static/img/mascots/scylla-looking-down.png differ diff --git a/_static/img/mascots/scylla-looking-up.png b/_static/img/mascots/scylla-looking-up.png new file mode 100644 index 00000000..6f10405f Binary files /dev/null and b/_static/img/mascots/scylla-looking-up.png differ diff --git a/_static/img/mascots/scylla-magnifying-glass-fronting.png b/_static/img/mascots/scylla-magnifying-glass-fronting.png new file mode 100644 index 00000000..e368cae1 Binary files /dev/null and b/_static/img/mascots/scylla-magnifying-glass-fronting.png differ diff --git a/_static/img/mascots/scylla-magnifying-glass.png b/_static/img/mascots/scylla-magnifying-glass.png new file mode 100644 index 00000000..74ad6695 Binary files /dev/null and b/_static/img/mascots/scylla-magnifying-glass.png differ diff --git a/_static/img/mascots/scylla-manager.svg b/_static/img/mascots/scylla-manager.svg new file mode 100644 index 00000000..6ba9ed93 --- /dev/null +++ b/_static/img/mascots/scylla-manager.svg @@ -0,0 +1 @@ +scylla-manager-2 diff --git a/_static/img/mascots/scylla-monitor.svg b/_static/img/mascots/scylla-monitor.svg new file mode 100644 index 00000000..48bec7dd --- /dev/null +++ b/_static/img/mascots/scylla-monitor.svg @@ -0,0 +1 @@ +scylla-monitor diff --git a/_static/img/mascots/scylla-movement-fast.png b/_static/img/mascots/scylla-movement-fast.png new file mode 100644 index 00000000..956d1dd0 Binary files /dev/null and b/_static/img/mascots/scylla-movement-fast.png differ diff --git a/_static/img/mascots/scylla-movement.png b/_static/img/mascots/scylla-movement.png new file mode 100644 index 00000000..7ee2b043 Binary files /dev/null and b/_static/img/mascots/scylla-movement.png differ diff --git a/_static/img/mascots/scylla-onpremise.png b/_static/img/mascots/scylla-onpremise.png new file mode 100644 index 00000000..3b2dc8f1 Binary files /dev/null and b/_static/img/mascots/scylla-onpremise.png differ diff --git a/_static/img/mascots/scylla-opensource.svg b/_static/img/mascots/scylla-opensource.svg new file mode 100644 index 00000000..299e9cb9 --- /dev/null +++ b/_static/img/mascots/scylla-opensource.svg @@ -0,0 +1 @@ +Plan de travail 1 diff --git a/_static/img/mascots/scylla-operator.svg b/_static/img/mascots/scylla-operator.svg new file mode 100644 index 00000000..655a450b --- /dev/null +++ b/_static/img/mascots/scylla-operator.svg @@ -0,0 +1 @@ +scylla-operator diff --git a/_static/img/mascots/scylla-plugin.png b/_static/img/mascots/scylla-plugin.png new file mode 100644 index 00000000..b28dc857 Binary files /dev/null and b/_static/img/mascots/scylla-plugin.png differ diff --git a/_static/img/mascots/scylla-release-mascot.png b/_static/img/mascots/scylla-release-mascot.png new file mode 100644 index 00000000..09342ac6 Binary files /dev/null and b/_static/img/mascots/scylla-release-mascot.png differ diff --git a/_static/img/mascots/scylla-repair.png b/_static/img/mascots/scylla-repair.png new file mode 100644 index 00000000..9b4c613e Binary files /dev/null and b/_static/img/mascots/scylla-repair.png differ diff --git a/_static/img/mascots/scylla-server.png b/_static/img/mascots/scylla-server.png new file mode 100644 index 00000000..96dc7852 Binary files /dev/null and b/_static/img/mascots/scylla-server.png differ diff --git a/_static/img/mascots/scylla-sleeping.png b/_static/img/mascots/scylla-sleeping.png new file mode 100644 index 00000000..f88598e0 Binary files /dev/null and b/_static/img/mascots/scylla-sleeping.png differ diff --git a/_static/img/mascots/scylla-tall-measure.png b/_static/img/mascots/scylla-tall-measure.png new file mode 100644 index 00000000..6f0ca146 Binary files /dev/null and b/_static/img/mascots/scylla-tall-measure.png differ diff --git a/_static/img/mascots/scylla-university.png b/_static/img/mascots/scylla-university.png new file mode 100644 index 00000000..b3d06211 Binary files /dev/null and b/_static/img/mascots/scylla-university.png differ diff --git a/_static/img/mascots/scylla-weights.png b/_static/img/mascots/scylla-weights.png new file mode 100644 index 00000000..b070bb02 Binary files /dev/null and b/_static/img/mascots/scylla-weights.png differ diff --git a/_static/img/mascots/scylla-window-cleaning.png b/_static/img/mascots/scylla-window-cleaning.png new file mode 100644 index 00000000..6a8b16a6 Binary files /dev/null and b/_static/img/mascots/scylla-window-cleaning.png differ diff --git a/_static/img/mascots/scylla-with-computer-2.png b/_static/img/mascots/scylla-with-computer-2.png new file mode 100644 index 00000000..f3b8b298 Binary files /dev/null and b/_static/img/mascots/scylla-with-computer-2.png differ diff --git a/_static/img/mascots/scylla-with-computer.png b/_static/img/mascots/scylla-with-computer.png new file mode 100644 index 00000000..b38a6fbb Binary files /dev/null and b/_static/img/mascots/scylla-with-computer.png differ diff --git a/_static/img/mascots/scylla-with-linux.png b/_static/img/mascots/scylla-with-linux.png new file mode 100644 index 00000000..954bf13b Binary files /dev/null and b/_static/img/mascots/scylla-with-linux.png differ diff --git a/_static/img/mascots/scylla-writting.png b/_static/img/mascots/scylla-writting.png new file mode 100644 index 00000000..d35a13d3 Binary files /dev/null and b/_static/img/mascots/scylla-writting.png differ diff --git a/_static/img/menu.svg b/_static/img/menu.svg new file mode 100644 index 00000000..30ea1d90 --- /dev/null +++ b/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/_static/img/programming_languages/go-lang.png b/_static/img/programming_languages/go-lang.png new file mode 100644 index 00000000..57006b20 Binary files /dev/null and b/_static/img/programming_languages/go-lang.png differ diff --git a/_static/img/programming_languages/java.png b/_static/img/programming_languages/java.png new file mode 100644 index 00000000..f9639c93 Binary files /dev/null and b/_static/img/programming_languages/java.png differ diff --git a/_static/img/programming_languages/javascript.png b/_static/img/programming_languages/javascript.png new file mode 100644 index 00000000..9bca9f37 Binary files /dev/null and b/_static/img/programming_languages/javascript.png differ diff --git a/_static/img/programming_languages/php.png b/_static/img/programming_languages/php.png new file mode 100644 index 00000000..951bf70a Binary files /dev/null and b/_static/img/programming_languages/php.png differ diff --git a/_static/img/programming_languages/python.png b/_static/img/programming_languages/python.png new file mode 100644 index 00000000..0577e602 Binary files /dev/null and b/_static/img/programming_languages/python.png differ diff --git a/_static/img/programming_languages/rust.png b/_static/img/programming_languages/rust.png new file mode 100644 index 00000000..b3d56391 Binary files /dev/null and b/_static/img/programming_languages/rust.png differ diff --git a/_static/js/main.bundle.js b/_static/js/main.bundle.js new file mode 100644 index 00000000..190a4164 --- /dev/null +++ b/_static/js/main.bundle.js @@ -0,0 +1,2 @@ +/*! For license information please see main.bundle.js.LICENSE.txt */ +(self.webpackChunksphinx_scylladb_theme=self.webpackChunksphinx_scylladb_theme||[]).push([[179],{277:(t,e,n)=>{var i;self,i=function(t){return function(){"use strict";var e={"./js/foundation.abide.js":function(t,e,n){n.r(e),n.d(e,{Abide:function(){return f}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.plugin.js"),s=n("./js/foundation.core.utils.js");function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}function l(t,e){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{};this.$element=t,this.options=o().extend(!0,{},d.defaults,this.$element.data(),e),this.isEnabled=!0,this.formnovalidate=null,this.className="Abide",this._init()}},{key:"_init",value:function(){var t=this;this.$inputs=o().merge(this.$element.find("input").not('[type="submit"]'),this.$element.find("textarea, select")),this.$submits=this.$element.find('[type="submit"]');var e=this.$element.find("[data-abide-error]");this.options.a11yAttributes&&(this.$inputs.each((function(e,n){return t.addA11yAttributes(o()(n))})),e.each((function(e,n){return t.addGlobalErrorA11yAttributes(o()(n))}))),this._events()}},{key:"_events",value:function(){var t=this;this.$element.off(".abide").on("reset.zf.abide",(function(){t.resetForm()})).on("submit.zf.abide",(function(){return t.validateForm()})),this.$submits.off("click.zf.abide keydown.zf.abide").on("click.zf.abide keydown.zf.abide",(function(e){e.key&&" "!==e.key&&"Enter"!==e.key||(e.preventDefault(),t.formnovalidate=null!==e.target.getAttribute("formnovalidate"),t.$element.submit())})),"fieldChange"===this.options.validateOn&&this.$inputs.off("change.zf.abide").on("change.zf.abide",(function(e){t.validateInput(o()(e.target))})),this.options.liveValidate&&this.$inputs.off("input.zf.abide").on("input.zf.abide",(function(e){t.validateInput(o()(e.target))})),this.options.validateOnBlur&&this.$inputs.off("blur.zf.abide").on("blur.zf.abide",(function(e){t.validateInput(o()(e.target))}))}},{key:"_reflow",value:function(){this._init()}},{key:"_validationIsDisabled",value:function(){return!1===this.isEnabled||("boolean"==typeof this.formnovalidate?this.formnovalidate:!!this.$submits.length&&null!==this.$submits[0].getAttribute("formnovalidate"))}},{key:"enableValidation",value:function(){this.isEnabled=!0}},{key:"disableValidation",value:function(){this.isEnabled=!1}},{key:"requiredCheck",value:function(t){if(!t.attr("required"))return!0;var e=!0;switch(t[0].type){case"checkbox":e=t[0].checked;break;case"select":case"select-one":case"select-multiple":var n=t.find("option:selected");n.length&&n.val()||(e=!1);break;default:t.val()&&t.val().length||(e=!1)}return e}},{key:"findFormError",value:function(t,e){var n=this,i=t.length?t[0].id:"",o=t.siblings(this.options.formErrorSelector);return o.length||(o=t.parent().find(this.options.formErrorSelector)),i&&(o=o.add(this.$element.find('[data-form-error-for="'.concat(i,'"]')))),e&&(o=o.not("[data-form-error-on]"),e.forEach((function(e){o=(o=o.add(t.siblings('[data-form-error-on="'.concat(e,'"]')))).add(n.$element.find('[data-form-error-for="'.concat(i,'"][data-form-error-on="').concat(e,'"]')))}))),o}},{key:"findLabel",value:function(t){var e=t[0].id,n=this.$element.find('label[for="'.concat(e,'"]'));return n.length?n:t.closest("label")}},{key:"findRadioLabels",value:function(t){var e=this,n=t.map((function(t,n){var i=n.id,r=e.$element.find('label[for="'.concat(i,'"]'));return r.length||(r=o()(n).closest("label")),r[0]}));return o()(n)}},{key:"findCheckboxLabels",value:function(t){var e=this,n=t.map((function(t,n){var i=n.id,r=e.$element.find('label[for="'.concat(i,'"]'));return r.length||(r=o()(n).closest("label")),r[0]}));return o()(n)}},{key:"addErrorClasses",value:function(t,e){var n=this.findLabel(t),i=this.findFormError(t,e);n.length&&n.addClass(this.options.labelErrorClass),i.length&&i.addClass(this.options.formErrorClass),t.addClass(this.options.inputErrorClass).attr({"data-invalid":"","aria-invalid":!0}),i.filter(":visible").length&&this.addA11yErrorDescribe(t,i)}},{key:"addA11yAttributes",value:function(t){var e=this.findFormError(t),n=e.filter("label");if(e.length){var i=e.filter(":visible").first();if(i.length&&this.addA11yErrorDescribe(t,i),n.filter("[for]").length=s&&(i=!0)),!0!==this.initialized&&s>1||(n.each((function(t,n){i?e.removeErrorClasses(o()(n)):e.addErrorClasses(o()(n),["required"])})),i)}},{key:"matchValidation",value:function(t,e,n){var i=this;return n=!!n,-1===e.split(" ").map((function(e){return i.options.validators[e](t,n,t.parent())})).indexOf(!1)}},{key:"resetForm",value:function(){var t=this.$element,e=this.options;o()(".".concat(e.labelErrorClass),t).not("small").removeClass(e.labelErrorClass),o()(".".concat(e.inputErrorClass),t).not("small").removeClass(e.inputErrorClass),o()("".concat(e.formErrorSelector,".").concat(e.formErrorClass)).removeClass(e.formErrorClass),t.find("[data-abide-error]").css("display","none"),o()(":input",t).not(":button, :submit, :reset, :hidden, :radio, :checkbox, [data-abide-ignore]").val("").attr({"data-invalid":null,"aria-invalid":null}),o()(":input:radio",t).not("[data-abide-ignore]").prop("checked",!1).attr({"data-invalid":null,"aria-invalid":null}),o()(":input:checkbox",t).not("[data-abide-ignore]").prop("checked",!1).attr({"data-invalid":null,"aria-invalid":null}),t.trigger("formreset.zf.abide",[t])}},{key:"_destroy",value:function(){var t=this;this.$element.off(".abide").find("[data-abide-error]").css("display","none"),this.$inputs.off(".abide").each((function(){t.removeErrorClasses(o()(this))})),this.$submits.off(".abide")}}],n&&l(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),d}(r.Plugin);f.defaults={validateOn:"fieldChange",labelErrorClass:"is-invalid-label",inputErrorClass:"is-invalid-input",formErrorSelector:".form-error",formErrorClass:"is-visible",a11yAttributes:!0,a11yErrorLevel:"assertive",liveValidate:!1,validateOnBlur:!1,patterns:{alpha:/^[a-zA-Z]+$/,alpha_numeric:/^[a-zA-Z0-9]+$/,integer:/^[-+]?\d+$/,number:/^[-+]?\d*(?:[\.\,]\d+)?$/,card:/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(?:222[1-9]|2[3-6][0-9]{2}|27[0-1][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,cvv:/^([0-9]){3,4}$/,email:/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/,url:/^((?:(https?|ftps?|file|ssh|sftp):\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\))+(?:\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?\xab\xbb\u201c\u201d\u2018\u2019]))$/,domain:/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/,datetime:/^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/,date:/(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/,time:/^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/,dateISO:/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/,month_day_year:/^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/,day_month_year:/^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/,color:/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,website:{test:function(t){return f.defaults.patterns.domain.test(t)||f.defaults.patterns.url.test(t)}}},validators:{equalTo:function(t){return o()("#".concat(t.attr("data-equalto"))).val()===t.val()}}}},"./js/foundation.accordion.js":function(t,e,n){n.r(e),n.d(e,{Accordion:function(){return d}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.plugin.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.util.keyboard.js");function l(t){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},l(t)}function u(t,e){for(var n=0;n'),t.options.submenuToggle?(n.addClass("has-submenu-toggle"),n.children("a").after('")):n.attr({"aria-controls":r,"aria-expanded":s,id:e}),i.attr({"aria-labelledby":e,"aria-hidden":!s,role:"group",id:r})}));var e=this.$element.find(".is-active");e.length&&e.each((function(){t.down(o()(this))})),this._events()}},{key:"_events",value:function(){var t=this;this.$element.find("li").each((function(){var e=o()(this).children("[data-submenu]");e.length&&(t.options.submenuToggle?o()(this).children(".submenu-toggle").off("click.zf.accordionMenu").on("click.zf.accordionMenu",(function(){t.toggle(e)})):o()(this).children("a").off("click.zf.accordionMenu").on("click.zf.accordionMenu",(function(n){n.preventDefault(),t.toggle(e)})))})).on("keydown.zf.accordionMenu",(function(e){var n,i,s=o()(this),a=s.parent("ul").children("li"),l=s.children("[data-submenu]");a.each((function(t){if(o()(this).is(s))return n=a.eq(Math.max(0,t-1)).find("a").first(),i=a.eq(Math.min(t+1,a.length-1)).find("a").first(),o()(this).children("[data-submenu]:visible").length&&(i=s.find("li:first-child").find("a").first()),o()(this).is(":first-child")?n=s.parents("li").first().find("a").first():n.parents("li").first().children("[data-submenu]:visible").length&&(n=n.parents("li").find("li:last-child").find("a").first()),void(o()(this).is(":last-child")&&(i=s.parents("li").first().next("li").find("a").first()))})),r.Keyboard.handleKey(e,"AccordionMenu",{open:function(){l.is(":hidden")&&(t.down(l),l.find("li").first().find("a").first().focus())},close:function(){l.length&&!l.is(":hidden")?t.up(l):s.parent("[data-submenu]").length&&(t.up(s.parent("[data-submenu]")),s.parents("li").first().find("a").first().focus())},up:function(){return n.focus(),!0},down:function(){return i.focus(),!0},toggle:function(){return!t.options.submenuToggle&&(s.children("[data-submenu]").length?(t.toggle(s.children("[data-submenu]")),!0):void 0)},closeAll:function(){t.hideAll()},handled:function(t){t&&e.preventDefault()}})}))}},{key:"hideAll",value:function(){this.up(this.$element.find("[data-submenu]"))}},{key:"showAll",value:function(){this.down(this.$element.find("[data-submenu]"))}},{key:"toggle",value:function(t){t.is(":animated")||(t.is(":hidden")?this.down(t):this.up(t))}},{key:"down",value:function(t){var e=this;if(!this.options.multiOpen){var n=t.parentsUntil(this.$element).add(t).add(t.find(".is-active")),i=this.$element.find(".is-active").not(n);this.up(i)}t.addClass("is-active").attr({"aria-hidden":!1}),this.options.submenuToggle?t.prev(".submenu-toggle").attr({"aria-expanded":!0}):t.parent(".is-accordion-submenu-parent").attr({"aria-expanded":!0}),t.slideDown(this.options.slideSpeed,(function(){e.$element.trigger("down.zf.accordionMenu",[t])}))}},{key:"up",value:function(t){var e=this,n=t.find("[data-submenu]"),i=t.add(n);n.slideUp(0),i.removeClass("is-active").attr("aria-hidden",!0),this.options.submenuToggle?i.prev(".submenu-toggle").attr("aria-expanded",!1):i.parent(".is-accordion-submenu-parent").attr("aria-expanded",!1),t.slideUp(this.options.slideSpeed,(function(){e.$element.trigger("up.zf.accordionMenu",[t])}))}},{key:"_destroy",value:function(){this.$element.find("[data-submenu]").slideDown(0).css("display",""),this.$element.find("a").off("click.zf.accordionMenu"),this.$element.find("[data-is-parent-link]").detach(),this.options.submenuToggle&&(this.$element.find(".has-submenu-toggle").removeClass("has-submenu-toggle"),this.$element.find(".submenu-toggle").remove()),s.Nest.Burn(this.$element,"accordion")}}])&&u(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),p}(n("./js/foundation.core.plugin.js").Plugin);d.defaults={parentLink:!1,slideSpeed:250,submenuToggle:!1,submenuToggleText:"Toggle menu",multiOpen:!0}},"./js/foundation.core.js":function(t,e,n){n.r(e),n.d(e,{Foundation:function(){return l}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.utils.js"),s=n("./js/foundation.util.mediaQuery.js");function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}var l={version:"6.8.1",_plugins:{},_uuids:[],plugin:function(t,e){var n=e||u(t),i=c(n);this._plugins[i]=this[n]=t},registerPlugin:function(t,e){var n=e?c(e):u(t.constructor).toLowerCase();t.uuid=(0,r.GetYoDigits)(6,n),t.$element.attr("data-".concat(n))||t.$element.attr("data-".concat(n),t.uuid),t.$element.data("zfPlugin")||t.$element.data("zfPlugin",t),t.$element.trigger("init.zf.".concat(n)),this._uuids.push(t.uuid)},unregisterPlugin:function(t){var e=c(u(t.$element.data("zfPlugin").constructor));for(var n in this._uuids.splice(this._uuids.indexOf(t.uuid),1),t.$element.removeAttr("data-".concat(e)).removeData("zfPlugin").trigger("destroyed.zf.".concat(e)),t)"function"==typeof t[n]&&(t[n]=null)},reInit:function(t){var e=t instanceof o();try{if(e)t.each((function(){o()(this).data("zfPlugin")._init()}));else{var n=a(t),i=this;({object:function(t){t.forEach((function(t){t=c(t),o()("[data-"+t+"]").foundation("_init")}))},string:function(){t=c(t),o()("[data-"+t+"]").foundation("_init")},undefined:function(){this.object(Object.keys(i._plugins))}})[n](t)}}catch(t){console.error(t)}finally{return t}},reflow:function(t,e){void 0===e?e=Object.keys(this._plugins):"string"==typeof e&&(e=[e]);var n=this;o().each(e,(function(e,i){var r=n._plugins[i];o()(t).find("[data-"+i+"]").addBack("[data-"+i+"]").filter((function(){return void 0===o()(this).data("zfPlugin")})).each((function(){var t=o()(this),e={reflow:!0};t.attr("data-options")&&t.attr("data-options").split(";").forEach((function(t){var n,i=t.split(":").map((function(t){return t.trim()}));i[0]&&(e[i[0]]="true"===(n=i[1])||"false"!==n&&(isNaN(1*n)?n:parseFloat(n)))}));try{t.data("zfPlugin",new r(o()(this),e))}catch(t){console.error(t)}finally{return}}))}))},getFnName:u,addToJquery:function(){return o().fn.foundation=function(t){var e=a(t),n=o()(".no-js");if(n.length&&n.removeClass("no-js"),"undefined"===e)s.MediaQuery._init(),l.reflow(this);else{if("string"!==e)throw new TypeError("We're sorry, ".concat(e," is not a valid parameter. You must use a string representing the method you wish to invoke."));var i=Array.prototype.slice.call(arguments,1),r=this.data("zfPlugin");if(void 0===r||void 0===r[t])throw new ReferenceError("We're sorry, '"+t+"' is not an available method for "+(r?u(r):"this element")+".");1===this.length?r[t].apply(r,i):this.each((function(e,n){r[t].apply(o()(n).data("zfPlugin"),i)}))}return this},o()}};function u(t){if(void 0===Function.prototype.name){var e=/function\s([^(]{1,})\(/.exec(t.toString());return e&&e.length>1?e[1].trim():""}return void 0===t.prototype?t.constructor.name:t.prototype.constructor.name}function c(t){return t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}l.util={throttle:function(t,e){var n=null;return function(){var i=this,o=arguments;null===n&&(n=setTimeout((function(){t.apply(i,o),n=null}),e))}}},window.Foundation=l,function(){Date.now&&window.Date.now||(window.Date.now=Date.now=function(){return(new Date).getTime()});for(var t=["webkit","moz"],e=0;e0&&void 0!==arguments[0]?arguments[0]:6,e=arguments.length>1?arguments[1]:void 0,n="",i="0123456789abcdefghijklmnopqrstuvwxyz",o=i.length,r=0;r1&&void 0!==arguments[1]?arguments[1]:{},n=e.ignoreLeaveWindow,i=void 0!==n&&n,r=e.ignoreReappear,s=void 0!==r&&r;return function(e){for(var n=arguments.length,r=new Array(n>1?n-1:0),a=1;a'),e.data("savedHref",e.attr("href")).removeAttr("href").attr("tabindex",0),e.children("[data-submenu]").attr({"aria-hidden":!0,tabindex:0,role:"group"}),t._events(e)})),this.$submenus.each((function(){var e=o()(this);if(!e.find(".js-drilldown-back").length)switch(t.options.backButtonPosition){case"bottom":e.append(t.options.backButton);break;case"top":e.prepend(t.options.backButton);break;default:console.error("Unsupported backButtonPosition value '"+t.options.backButtonPosition+"'")}t._back(e)})),this.$submenus.addClass("invisible"),this.options.autoHeight||this.$submenus.addClass("drilldown-submenu-cover-previous"),this.$element.parent().hasClass("is-drilldown")||(this.$wrapper=o()(this.options.wrapper).addClass("is-drilldown"),this.options.animateHeight&&this.$wrapper.addClass("animate-height"),this.$element.wrap(this.$wrapper)),this.$wrapper=this.$element.parent(),this.$wrapper.css(this._getMaxDims())}},{key:"_resize",value:function(){this.$wrapper.css({"max-width":"none","min-height":"none"}),this.$wrapper.css(this._getMaxDims())}},{key:"_events",value:function(t){var e=this;t.off("click.zf.drilldown").on("click.zf.drilldown",(function(n){if(o()(n.target).parentsUntil("ul","li").hasClass("is-drilldown-submenu-parent")&&n.preventDefault(),e._show(t.parent("li")),e.options.closeOnClick){var i=o()("body");i.off(".zf.drilldown").on("click.zf.drilldown",(function(t){t.target===e.$element[0]||o().contains(e.$element[0],t.target)||(t.preventDefault(),e._hideAll(),i.off(".zf.drilldown"))}))}}))}},{key:"_registerEvents",value:function(){this.options.scrollTop&&(this._bindHandler=this._scrollTop.bind(this),this.$element.on("open.zf.drilldown hide.zf.drilldown close.zf.drilldown closed.zf.drilldown",this._bindHandler)),this.$element.on("mutateme.zf.trigger",this._resize.bind(this))}},{key:"_scrollTop",value:function(){var t=this,e=""!==t.options.scrollTopElement?o()(t.options.scrollTopElement):t.$element,n=parseInt(e.offset().top+t.options.scrollTopOffset,10);o()("html, body").stop(!0).animate({scrollTop:n},t.options.animationDuration,t.options.animationEasing,(function(){this===o()("html")[0]&&t.$element.trigger("scrollme.zf.drilldown")}))}},{key:"_keyboardEvents",value:function(){var t=this;this.$menuItems.add(this.$element.find(".js-drilldown-back > a, .is-submenu-parent-item > a")).on("keydown.zf.drilldown",(function(e){var n,i,s=o()(this),l=s.parent("li").parent("ul").children("li").children("a");l.each((function(t){if(o()(this).is(s))return n=l.eq(Math.max(0,t-1)),void(i=l.eq(Math.min(t+1,l.length-1)))})),r.Keyboard.handleKey(e,"Drilldown",{next:function(){if(s.is(t.$submenuAnchors))return t._show(s.parent("li")),s.parent("li").one((0,a.transitionend)(s),(function(){s.parent("li").find("ul li a").not(".js-drilldown-back a").first().focus()})),!0},previous:function(){return t._hide(s.parent("li").parent("ul")),s.parent("li").parent("ul").one((0,a.transitionend)(s),(function(){setTimeout((function(){s.parent("li").parent("ul").parent("li").children("a").first().focus()}),1)})),!0},up:function(){return n.focus(),!s.is(t.$element.find("> li:first-child > a"))},down:function(){return i.focus(),!s.is(t.$element.find("> li:last-child > a"))},close:function(){s.is(t.$element.find("> li > a"))||(t._hide(s.parent().parent()),s.parent().parent().siblings("a").focus())},open:function(){return(!t.options.parentLink||!s.attr("href"))&&(s.is(t.$menuItems)?s.is(t.$submenuAnchors)?(t._show(s.parent("li")),s.parent("li").one((0,a.transitionend)(s),(function(){s.parent("li").find("ul li a").not(".js-drilldown-back a").first().focus()})),!0):void 0:(t._hide(s.parent("li").parent("ul")),s.parent("li").parent("ul").one((0,a.transitionend)(s),(function(){setTimeout((function(){s.parent("li").parent("ul").parent("li").children("a").first().focus()}),1)})),!0))},handled:function(t){t&&e.preventDefault()}})}))}},{key:"_hideAll",value:function(){var t=this,e=this.$element.find(".is-drilldown-submenu.is-active");if(e.addClass("is-closing"),e.parent().closest("ul").removeClass("invisible"),this.options.autoHeight){var n=e.parent().closest("ul").data("calcHeight");this.$wrapper.css({height:n})}this.$element.trigger("close.zf.drilldown"),e.one((0,a.transitionend)(e),(function(){e.removeClass("is-active is-closing"),t.$element.trigger("closed.zf.drilldown")}))}},{key:"_back",value:function(t){var e=this;t.off("click.zf.drilldown"),t.children(".js-drilldown-back").on("click.zf.drilldown",(function(){e._hide(t);var n=t.parent("li").parent("ul").parent("li");n.length?e._show(n):e.$currentMenu=e.$element}))}},{key:"_menuLinkEvents",value:function(){var t=this;this.$menuItems.not(".is-drilldown-submenu-parent").off("click.zf.drilldown").on("click.zf.drilldown",(function(){setTimeout((function(){t._hideAll()}),0)}))}},{key:"_setShowSubMenuClasses",value:function(t,e){t.addClass("is-active").removeClass("invisible").attr("aria-hidden",!1),t.parent("li").attr("aria-expanded",!0),!0===e&&this.$element.trigger("open.zf.drilldown",[t])}},{key:"_setHideSubMenuClasses",value:function(t,e){t.removeClass("is-active").addClass("invisible").attr("aria-hidden",!0),t.parent("li").attr("aria-expanded",!1),!0===e&&t.trigger("hide.zf.drilldown",[t])}},{key:"_showMenu",value:function(t,e){var n=this;if(this.$element.find('li[aria-expanded="true"] > ul[data-submenu]').each((function(){n._setHideSubMenuClasses(o()(this))})),this.$currentMenu=t,t.is("[data-drilldown]"))return!0===e&&t.find("li > a").first().focus(),void(this.options.autoHeight&&this.$wrapper.css("height",t.data("calcHeight")));var i=t.children().first().parentsUntil("[data-drilldown]","[data-submenu]");i.each((function(r){0===r&&n.options.autoHeight&&n.$wrapper.css("height",o()(this).data("calcHeight"));var s=r===i.length-1;!0===s&&o()(this).one((0,a.transitionend)(o()(this)),(function(){!0===e&&t.find("li > a").first().focus()})),n._setShowSubMenuClasses(o()(this),s)}))}},{key:"_show",value:function(t){var e=t.children("[data-submenu]");t.attr("aria-expanded",!0),this.$currentMenu=e,t.parent().closest("ul").addClass("invisible"),e.addClass("is-active visible").removeClass("invisible").attr("aria-hidden",!1),this.options.autoHeight&&this.$wrapper.css({height:e.data("calcHeight")}),this.$element.trigger("open.zf.drilldown",[t])}},{key:"_hide",value:function(t){this.options.autoHeight&&this.$wrapper.css({height:t.parent().closest("ul").data("calcHeight")}),t.parent().closest("ul").removeClass("invisible"),t.parent("li").attr("aria-expanded",!1),t.attr("aria-hidden",!0),t.addClass("is-closing").one((0,a.transitionend)(t),(function(){t.removeClass("is-active is-closing visible"),t.blur().addClass("invisible")})),t.trigger("hide.zf.drilldown",[t])}},{key:"_getMaxDims",value:function(){var t=0,e={},n=this;return this.$submenus.add(this.$element).each((function(){var e=l.Box.GetDimensions(this).height;t=e>t?e:t,n.options.autoHeight&&o()(this).data("calcHeight",e)})),this.options.autoHeight?e.height=this.$currentMenu.data("calcHeight"):e["min-height"]="".concat(t,"px"),e["max-width"]="".concat(this.$element[0].getBoundingClientRect().width,"px"),e}},{key:"_destroy",value:function(){o()("body").off(".zf.drilldown"),this.options.scrollTop&&this.$element.off(".zf.drilldown",this._bindHandler),this._hideAll(),this.$element.off("mutateme.zf.trigger"),s.Nest.Burn(this.$element,"drilldown"),this.$element.unwrap().find(".js-drilldown-back, .is-submenu-parent-item").remove().end().find(".is-active, .is-closing, .is-drilldown-submenu").removeClass("is-active is-closing is-drilldown-submenu").off("transitionend otransitionend webkitTransitionEnd").end().find("[data-submenu]").removeAttr("aria-hidden tabindex role"),this.$submenuAnchors.each((function(){o()(this).off(".zf.drilldown")})),this.$element.find("[data-is-parent-link]").detach(),this.$submenus.removeClass("drilldown-submenu-cover-previous invisible"),this.$element.find("a").each((function(){var t=o()(this);t.removeAttr("tabindex"),t.data("savedHref")&&t.attr("href",t.data("savedHref")).removeData("savedHref")}))}}])&&c(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),v}(n("./js/foundation.core.plugin.js").Plugin);h.defaults={autoApplyClass:!0,backButton:'
  • Back
  • ',backButtonPosition:"top",wrapper:"
    ",parentLink:!1,closeOnClick:!1,autoHeight:!1,animateHeight:!1,scrollTop:!1,scrollTopElement:"",scrollTopOffset:0,animationDuration:500,animationEasing:"swing"}},"./js/foundation.dropdown.js":function(t,e,n){n.r(e),n.d(e,{Dropdown:function(){return v}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.keyboard.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.positionable.js"),l=n("./js/foundation.util.triggers.js"),u=n("./js/foundation.util.touch.js");function c(t){return c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},c(t)}function f(t,e){for(var n=0;n-1,l=s?t.$tabs:r.siblings("li").add(r);l.each((function(t){if(o()(this).is(r))return n=l.eq(t-1),void(i=l.eq(t+1))}));var u=function(){i.children("a:first").focus(),e.preventDefault()},c=function(){n.children("a:first").focus(),e.preventDefault()},f=function(){var n=r.children("ul.is-dropdown-submenu");n.length&&(t._show(n),r.find("li > a:first").focus(),e.preventDefault())},d=function(){var n=r.parent("ul").parent("li");n.children("a:first").focus(),t._hide(n),e.preventDefault()},h={open:f,close:function(){t._hide(t.$element),t.$menuItems.eq(0).children("a").focus(),e.preventDefault()}};s?t._isVertical()?t._isRtl()?o().extend(h,{down:u,up:c,next:d,previous:f}):o().extend(h,{down:u,up:c,next:f,previous:d}):t._isRtl()?o().extend(h,{next:c,previous:u,down:f,up:d}):o().extend(h,{next:u,previous:c,down:f,up:d}):t._isRtl()?o().extend(h,{next:d,previous:f,down:u,up:c}):o().extend(h,{next:f,previous:d,down:u,up:c}),a.Keyboard.handleKey(e,"DropdownMenu",h)}))}},{key:"_addBodyHandler",value:function(){var t=this,e=o()(document.body);this._removeBodyHandler(),e.on("click.zf.dropdownMenu tap.zf.dropdownMenu",(function(e){o()(e.target).closest(t.$element).length||(t._hide(),t._removeBodyHandler())}))}},{key:"_removeBodyHandler",value:function(){o()(document.body).off("click.zf.dropdownMenu tap.zf.dropdownMenu")}},{key:"_show",value:function(t){var e=this.$tabs.index(this.$tabs.filter((function(e,n){return o()(n).find(t).length>0}))),n=t.parent("li.is-dropdown-submenu-parent").siblings("li.is-dropdown-submenu-parent");this._hide(n,e),t.css("visibility","hidden").addClass("js-dropdown-active").parent("li.is-dropdown-submenu-parent").addClass("is-active");var i=u.Box.ImNotTouchingYou(t,null,!0);if(!i){var r="left"===this.options.alignment?"-right":"-left",s=t.parent(".is-dropdown-submenu-parent");s.removeClass("opens".concat(r)).addClass("opens-".concat(this.options.alignment)),(i=u.Box.ImNotTouchingYou(t,null,!0))||s.removeClass("opens-".concat(this.options.alignment)).addClass("opens-inner"),this.changed=!0}t.css("visibility",""),this.options.closeOnClick&&this._addBodyHandler(),this.$element.trigger("show.zf.dropdownMenu",[t])}},{key:"_hide",value:function(t,e){var n;if((n=t&&t.length?t:void 0!==e?this.$tabs.not((function(t){return t===e})):this.$element).hasClass("is-active")||n.find(".is-active").length>0){var i=n.find("li.is-active");if(i.add(n).attr({"data-is-click":!1}).removeClass("is-active"),n.find("ul.js-dropdown-active").removeClass("js-dropdown-active"),this.changed||n.find("opens-inner").length){var o="left"===this.options.alignment?"right":"left";n.find("li.is-dropdown-submenu-parent").add(n).removeClass("opens-inner opens-".concat(this.options.alignment)).addClass("opens-".concat(o)),this.changed=!1}clearTimeout(i.data("_delay")),this._removeBodyHandler(),this.$element.trigger("hide.zf.dropdownMenu",[n])}}},{key:"_destroy",value:function(){this.$menuItems.off(".zf.dropdownMenu").removeAttr("data-is-click").removeClass("is-right-arrow is-left-arrow is-down-arrow opens-right opens-left opens-inner"),o()(document.body).off(".zf.dropdownMenu"),l.Nest.Burn(this.$element,"dropdown")}}])&&d(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),m}(r.Plugin);v.defaults={disableHover:!1,disableHoverOnTouch:!0,autoclose:!0,hoverDelay:50,clickOpen:!1,closingTime:500,alignment:"auto",closeOnClick:!0,closeOnClickInside:!0,verticalClass:"vertical",rightClass:"align-right",forceFollow:!0}},"./js/foundation.equalizer.js":function(t,e,n){n.r(e),n.d(e,{Equalizer:function(){return d}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.mediaQuery.js"),s=n("./js/foundation.util.imageLoader.js"),a=n("./js/foundation.core.utils.js");function l(t){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},l(t)}function u(t,e){for(var n=0;n0,this.isNested=this.$element.parentsUntil(document.body,"[data-equalizer]").length>0,this.isOn=!1,this._bindHandler={onResizeMeBound:this._onResizeMe.bind(this),onPostEqualizedBound:this._onPostEqualized.bind(this)};var n,i=this.$element.find("img");this.options.equalizeOn?(n=this._checkMQ(),o()(window).on("changed.zf.mediaquery",this._checkMQ.bind(this))):this._events(),(void 0!==n&&!1===n||void 0===n)&&(i.length?(0,s.onImagesLoaded)(i,this._reflow.bind(this)):this._reflow())}},{key:"_pauseEvents",value:function(){this.isOn=!1,this.$element.off({".zf.equalizer":this._bindHandler.onPostEqualizedBound,"resizeme.zf.trigger":this._bindHandler.onResizeMeBound,"mutateme.zf.trigger":this._bindHandler.onResizeMeBound})}},{key:"_onResizeMe",value:function(){this._reflow()}},{key:"_onPostEqualized",value:function(t){t.target!==this.$element[0]&&this._reflow()}},{key:"_events",value:function(){this._pauseEvents(),this.hasNested?this.$element.on("postequalized.zf.equalizer",this._bindHandler.onPostEqualizedBound):(this.$element.on("resizeme.zf.trigger",this._bindHandler.onResizeMeBound),this.$element.on("mutateme.zf.trigger",this._bindHandler.onResizeMeBound)),this.isOn=!0}},{key:"_checkMQ",value:function(){var t=!r.MediaQuery.is(this.options.equalizeOn);return t?this.isOn&&(this._pauseEvents(),this.$watched.css("height","auto")):this.isOn||this._events(),t}},{key:"_killswitch",value:function(){}},{key:"_reflow",value:function(){if(!this.options.equalizeOnStack&&this._isStacked())return this.$watched.css("height","auto"),!1;this.options.equalizeByRow?this.getHeightsByRow(this.applyHeightByRow.bind(this)):this.getHeights(this.applyHeight.bind(this))}},{key:"_isStacked",value:function(){return!this.$watched[0]||!this.$watched[1]||this.$watched[0].getBoundingClientRect().top!==this.$watched[1].getBoundingClientRect().top}},{key:"getHeights",value:function(t){for(var e=[],n=0,i=this.$watched.length;nn;if(this.scrollPos=n,n0&&"push"===this.options.transition&&(this.options.contentScroll=!1);var r=this.$element.attr("class").match(/\bin-canvas-for-(\w+)/);r&&2===r.length?this.options.inCanvasOn=r[1]:this.options.inCanvasOn&&this.$element.addClass("in-canvas-for-".concat(this.options.inCanvasOn)),this.options.inCanvasOn&&this._checkInCanvas(),this._removeContentClasses()}},{key:"_events",value:function(){var t=this;this.$element.off(".zf.trigger .zf.offCanvas").on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":this.close.bind(this),"toggle.zf.trigger":this.toggle.bind(this),"keydown.zf.offCanvas":this._handleKeyboard.bind(this)}),!0===this.options.closeOnClick&&(this.options.contentOverlay?this.$overlay:this.$content).on({"click.zf.offCanvas":this.close.bind(this)}),this.options.inCanvasOn&&o()(window).on("changed.zf.mediaquery",(function(){t._checkInCanvas()}))}},{key:"_setMQChecker",value:function(){var t=this;this.onLoadListener=(0,s.onLoad)(o()(window),(function(){l.MediaQuery.atLeast(t.options.revealOn)&&t.reveal(!0)})),o()(window).on("changed.zf.mediaquery",(function(){l.MediaQuery.atLeast(t.options.revealOn)?t.reveal(!0):t.reveal(!1)}))}},{key:"_checkInCanvas",value:function(){this.isInCanvas=l.MediaQuery.atLeast(this.options.inCanvasOn),!0===this.isInCanvas&&this.close()}},{key:"_removeContentClasses",value:function(t){"boolean"!=typeof t?this.$content.removeClass(this.contentClasses.base.join(" ")):!1===t&&this.$content.removeClass("has-reveal-".concat(this.position))}},{key:"_addContentClasses",value:function(t){this._removeContentClasses(t),"boolean"!=typeof t?this.$content.addClass("has-transition-".concat(this.options.transition," has-position-").concat(this.position)):!0===t&&this.$content.addClass("has-reveal-".concat(this.position))}},{key:"_fixStickyElements",value:function(){this.$sticky.each((function(t,e){var n=o()(e);if("fixed"===n.css("position")){var i=parseInt(n.css("top"),10);n.data("offCanvasSticky",{top:i});var r=o()(document).scrollTop()+i;n.css({top:"".concat(r,"px"),width:"100%",transition:"none"})}}))}},{key:"_unfixStickyElements",value:function(){this.$sticky.each((function(t,e){var n=o()(e),i=n.data("offCanvasSticky");"object"===c(i)&&(n.css({top:"".concat(i.top,"px"),width:"",transition:""}),n.data("offCanvasSticky",""))}))}},{key:"reveal",value:function(t){t?(this.close(),this.isRevealed=!0,this.$element.attr("aria-hidden","false"),this.$element.off("open.zf.trigger toggle.zf.trigger"),this.$element.removeClass("is-closed")):(this.isRevealed=!1,this.$element.attr("aria-hidden","true"),this.$element.off("open.zf.trigger toggle.zf.trigger").on({"open.zf.trigger":this.open.bind(this),"toggle.zf.trigger":this.toggle.bind(this)}),this.$element.addClass("is-closed")),this._addContentClasses(t)}},{key:"_stopScrolling",value:function(){return!1}},{key:"_recordScrollable",value:function(t){this.lastY=t.touches[0].pageY}},{key:"_preventDefaultAtEdges",value:function(t){var e=this,n=t.data,i=e.lastY-t.touches[0].pageY;e.lastY=t.touches[0].pageY,n._canScroll(i,e)||t.preventDefault()}},{key:"_scrollboxTouchMoved",value:function(t){var e=this,n=t.data,i=e.closest("[data-off-canvas], [data-off-canvas-scrollbox-outer]"),o=e.lastY-t.touches[0].pageY;i.lastY=e.lastY=t.touches[0].pageY,t.stopPropagation(),n._canScroll(o,e)||(n._canScroll(o,i)?i.scrollTop+=o:t.preventDefault())}},{key:"_canScroll",value:function(t,e){var n=t<0,i=t>0,o=e.scrollTop>0,r=e.scrollTop1&&this.geoSync(),this.options.accessible&&this.$wrapper.attr("tabindex",0)}},{key:"_loadBullets",value:function(){this.$bullets=this.$element.find(".".concat(this.options.boxOfBullets)).find("button")}},{key:"geoSync",value:function(){var t=this;this.timer=new a.Timer(this.$element,{duration:this.options.timerDelay,infinite:!1},(function(){t.changeSlide(!0)})),this.timer.start()}},{key:"_prepareForOrbit",value:function(){this._setWrapperHeight()}},{key:"_setWrapperHeight",value:function(t){var e,n=0,i=0,r=this;this.$slides.each((function(){e=this.getBoundingClientRect().height,o()(this).attr("data-slide",i),/mui/g.test(o()(this)[0].className)||r.$slides.filter(".is-active")[0]===r.$slides.eq(i)[0]||o()(this).css({display:"none"}),n=e>n?e:n,i++})),i===this.$slides.length&&(this.$wrapper.css({height:n}),t&&t(n))}},{key:"_setSlideHeight",value:function(t){this.$slides.each((function(){o()(this).css("max-height",t)}))}},{key:"_events",value:function(){var t=this;this.$element.off(".resizeme.zf.trigger").on({"resizeme.zf.trigger":this._prepareForOrbit.bind(this)}),this.$slides.length>1&&(this.options.swipe&&this.$slides.off("swipeleft.zf.orbit swiperight.zf.orbit").on("swipeleft.zf.orbit",(function(e){e.preventDefault(),t.changeSlide(!0)})).on("swiperight.zf.orbit",(function(e){e.preventDefault(),t.changeSlide(!1)})),this.options.autoPlay&&(this.$slides.on("click.zf.orbit",(function(){t.$element.data("clickedOn",!t.$element.data("clickedOn")),t.timer[t.$element.data("clickedOn")?"pause":"start"]()})),this.options.pauseOnHover&&this.$element.on("mouseenter.zf.orbit",(function(){t.timer.pause()})).on("mouseleave.zf.orbit",(function(){t.$element.data("clickedOn")||t.timer.start()}))),this.options.navButtons&&this.$element.find(".".concat(this.options.nextClass,", .").concat(this.options.prevClass)).attr("tabindex",0).on("click.zf.orbit touchend.zf.orbit",(function(e){e.preventDefault(),t.changeSlide(o()(this).hasClass(t.options.nextClass))})),this.options.bullets&&this.$bullets.on("click.zf.orbit touchend.zf.orbit",(function(){if(/is-active/g.test(this.className))return!1;var e=o()(this).data("slide"),n=e>t.$slides.filter(".is-active").data("slide"),i=t.$slides.eq(e);t.changeSlide(n,i,e)})),this.options.accessible&&this.$wrapper.add(this.$bullets).on("keydown.zf.orbit",(function(e){r.Keyboard.handleKey(e,"Orbit",{next:function(){t.changeSlide(!0)},previous:function(){t.changeSlide(!1)},handled:function(){o()(e.target).is(t.$bullets)&&t.$bullets.filter(".is-active").focus()}})})))}},{key:"_reset",value:function(){void 0!==this.$slides&&this.$slides.length>1&&(this.$element.off(".zf.orbit").find("*").off(".zf.orbit"),this.options.autoPlay&&this.timer.restart(),this.$slides.each((function(t){o()(t).removeClass("is-active is-active is-in").removeAttr("aria-live").hide()})),this.$slides.first().addClass("is-active").show(),this.$element.trigger("slidechange.zf.orbit",[this.$slides.first()]),this.options.bullets&&this._updateBullets(0))}},{key:"changeSlide",value:function(t,e,n){if(this.$slides){var i=this.$slides.filter(".is-active").eq(0);if(/mui/g.test(i[0].className))return!1;var o,r=this.$slides.first(),a=this.$slides.last(),l=t?"Right":"Left",u=t?"Left":"Right",c=this;(o=e||(t?this.options.infiniteWrap?i.next(".".concat(this.options.slideClass)).length?i.next(".".concat(this.options.slideClass)):r:i.next(".".concat(this.options.slideClass)):this.options.infiniteWrap?i.prev(".".concat(this.options.slideClass)).length?i.prev(".".concat(this.options.slideClass)):a:i.prev(".".concat(this.options.slideClass)))).length&&(this.$element.trigger("beforeslidechange.zf.orbit",[i,o]),this.options.bullets&&(n=n||this.$slides.index(o),this._updateBullets(n)),this.options.useMUI&&!this.$element.is(":hidden")?(s.Motion.animateIn(o.addClass("is-active"),this.options["animInFrom".concat(l)],(function(){o.css({display:"block"}).attr("aria-live","polite")})),s.Motion.animateOut(i.removeClass("is-active"),this.options["animOutTo".concat(u)],(function(){i.removeAttr("aria-live"),c.options.autoPlay&&!c.timer.isPaused&&c.timer.restart()}))):(i.removeClass("is-active is-in").removeAttr("aria-live").hide(),o.addClass("is-active is-in").attr("aria-live","polite").show(),this.options.autoPlay&&!this.timer.isPaused&&this.timer.restart()),this.$element.trigger("slidechange.zf.orbit",[o]))}}},{key:"_updateBullets",value:function(t){var e=this.$bullets.filter(".is-active"),n=this.$bullets.not(".is-active"),i=this.$bullets.eq(t);e.removeClass("is-active").blur(),i.addClass("is-active");var r=e.children("[data-slide-active-label]").last();if(!r.length){var s=e.children("span");n.toArray().map((function(t){return o()(t).children("span").length})).every((function(t){return t1?i[0]:"small",a=i.length>1?i[1]:i[0];null!==v[a]&&(t[s]=v[a])}this.rules=t}this._getAllOptions(),o().isEmptyObject(this.rules)||this._checkMediaQueries()}},{key:"_getAllOptions",value:function(){var t=this;for(var e in t.allOptions={},v)if(v.hasOwnProperty(e)){var n=v[e];try{var i=o()("
      "),r=new n.plugin(i,t.options);for(var s in r.options)if(r.options.hasOwnProperty(s)&&"zfPlugin"!==s){var a=r.options[s];t.allOptions[s]=a}r.destroy()}catch(t){console.warn("Warning: Problems getting Accordion/Tab options: ".concat(t))}}}},{key:"_events",value:function(){this._changedZfMediaQueryHandler=this._checkMediaQueries.bind(this),o()(window).on("changed.zf.mediaquery",this._changedZfMediaQueryHandler)}},{key:"_checkMediaQueries",value:function(){var t,e=this;o().each(this.rules,(function(e){r.MediaQuery.atLeast(e)&&(t=e)})),t&&(this.currentPlugin instanceof this.rules[t].plugin||(o().each(v,(function(t,n){e.$element.removeClass(n.cssClass)})),this.$element.addClass(this.rules[t].cssClass),this.currentPlugin&&(!this.currentPlugin.$element.data("zfPlugin")&&this.storezfData&&this.currentPlugin.$element.data("zfPlugin",this.storezfData),this.currentPlugin.destroy()),this._handleMarkup(this.rules[t].cssClass),this.currentRule=this.rules[t],this.currentPlugin=new this.currentRule.plugin(this.$element,this.options),this.storezfData=this.currentPlugin.$element.data("zfPlugin")))}},{key:"_handleMarkup",value:function(t){var e=this,n="accordion",i=o()("[data-tabs-content="+this.$element.attr("id")+"]");if(i.length&&(n="tabs"),n!==t){var r=e.allOptions.linkClass?e.allOptions.linkClass:"tabs-title",a=e.allOptions.panelClass?e.allOptions.panelClass:"tabs-panel";this.$element.removeAttr("role");var l=this.$element.children("."+r+",[data-accordion-item]").removeClass(r).removeClass("accordion-item").removeAttr("data-accordion-item"),u=l.children("a").removeClass("accordion-title");if("tabs"===n?(i=i.children("."+a).removeClass(a).removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby")).children("a").removeAttr("role").removeAttr("aria-controls").removeAttr("aria-selected"):i=l.children("[data-tab-content]").removeClass("accordion-content"),i.css({display:"",visibility:""}),l.css({display:"",visibility:""}),"accordion"===t)i.each((function(t,n){o()(n).appendTo(l.get(t)).addClass("accordion-content").attr("data-tab-content","").removeClass("is-active").css({height:""}),o()("[data-tabs-content="+e.$element.attr("id")+"]").after('
      ').detach(),l.addClass("accordion-item").attr("data-accordion-item",""),u.addClass("accordion-title")}));else if("tabs"===t){var c=o()("[data-tabs-content="+e.$element.attr("id")+"]"),f=o()("#tabs-placeholder-"+e.$element.attr("id"));f.length?(c=o()('
      ').insertAfter(f).attr("data-tabs-content",e.$element.attr("id")),f.remove()):c=o()('
      ').insertAfter(e.$element).attr("data-tabs-content",e.$element.attr("id")),i.each((function(t,e){var n=o()(e).appendTo(c).addClass(a),i=u.get(t).hash.slice(1),r=o()(e).attr("id")||(0,s.GetYoDigits)(6,"accordion");i!==r&&(""!==i?o()(e).attr("id",i):(i=r,o()(e).attr("id",i),o()(u.get(t)).attr("href",o()(u.get(t)).attr("href").replace("#","")+"#"+i))),o()(l.get(t)).hasClass("is-active")&&n.addClass("is-active")})),l.addClass(r)}}}},{key:"open",value:function(){var t;if(this.currentRule&&"function"==typeof this.currentRule.open)return(t=this.currentRule).open.apply(t,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"close",value:function(){var t;if(this.currentRule&&"function"==typeof this.currentRule.close)return(t=this.currentRule).close.apply(t,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"toggle",value:function(){var t;if(this.currentRule&&"function"==typeof this.currentRule.toggle)return(t=this.currentRule).toggle.apply(t,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"_destroy",value:function(){this.currentPlugin&&this.currentPlugin.destroy(),o()(window).off("changed.zf.mediaquery",this._changedZfMediaQueryHandler)}}],n&&c(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),u}(a.Plugin);m.defaults={}},"./js/foundation.responsiveMenu.js":function(t,e,n){n.r(e),n.d(e,{ResponsiveMenu:function(){return m}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.mediaQuery.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.core.plugin.js"),l=n("./js/foundation.dropdownMenu.js"),u=n("./js/foundation.drilldown.js"),c=n("./js/foundation.accordionMenu.js");function f(t){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},f(t)}function d(t,e){for(var n=0;n1?i[0]:"small",l=i.length>1?i[1]:i[0];null!==v[l]&&(t[a]=v[l])}this.rules=t}o().isEmptyObject(this.rules)||this._checkMediaQueries(),this.$element.attr("data-mutate",this.$element.attr("data-mutate")||(0,s.GetYoDigits)(6,"responsive-menu"))}},{key:"_events",value:function(){var t=this;o()(window).on("changed.zf.mediaquery",(function(){t._checkMediaQueries()}))}},{key:"_checkMediaQueries",value:function(){var t,e=this;o().each(this.rules,(function(e){r.MediaQuery.atLeast(e)&&(t=e)})),t&&(this.currentPlugin instanceof this.rules[t].plugin||(o().each(v,(function(t,n){e.$element.removeClass(n.cssClass)})),this.$element.addClass(this.rules[t].cssClass),this.currentPlugin&&this.currentPlugin.destroy(),this.currentPlugin=new this.rules[t].plugin(this.$element,{})))}},{key:"_destroy",value:function(){this.currentPlugin.destroy(),o()(window).off(".zf.ResponsiveMenu")}}])&&d(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),u}(a.Plugin);m.defaults={}},"./js/foundation.responsiveToggle.js":function(t,e,n){n.r(e),n.d(e,{ResponsiveToggle:function(){return f}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.mediaQuery.js"),s=n("./js/foundation.util.motion.js");function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}function l(t,e){for(var n=0;n").addClass("reveal-overlay"+t).appendTo(this.options.appendTo)}},{key:"_updatePosition",value:function(){var t,e=this.$element.outerWidth(),n=o()(window).width(),i=this.$element.outerHeight(),r=o()(window).height(),s=null;t="auto"===this.options.hOffset?parseInt((n-e)/2,10):parseInt(this.options.hOffset,10),"auto"===this.options.vOffset?s=i>r?parseInt(Math.min(100,r/10),10):parseInt((r-i)/4,10):null!==this.options.vOffset&&(s=parseInt(this.options.vOffset,10)),null!==s&&this.$element.css({top:s+"px"}),this.$overlay&&"auto"===this.options.hOffset||(this.$element.css({left:t+"px"}),this.$element.css({margin:"0px"}))}},{key:"_events",value:function(){var t=this,e=this;this.$element.on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":function(n,i){if(n.target===e.$element[0]||o()(n.target).parents("[data-closable]")[0]===i)return t.close.apply(t)},"toggle.zf.trigger":this.toggle.bind(this),"resizeme.zf.trigger":function(){e._updatePosition()}}),this.options.closeOnClick&&this.options.overlay&&this.$overlay.off(".zf.reveal").on("click.zf.dropdown tap.zf.dropdown",(function(t){t.target!==e.$element[0]&&!o().contains(e.$element[0],t.target)&&o().contains(document,t.target)&&e.close()})),this.options.deepLink&&o()(window).on("hashchange.zf.reveal:".concat(this.id),this._handleState.bind(this))}},{key:"_handleState",value:function(){window.location.hash!=="#"+this.id||this.isActive?this.close():this.open()}},{key:"_disableScroll",value:function(t){t=t||o()(window).scrollTop(),o()(document).height()>o()(window).height()&&o()("html").css("top",-t)}},{key:"_enableScroll",value:function(t){t=t||parseInt(o()("html").css("top"),10),o()(document).height()>o()(window).height()&&(o()("html").css("top",""),o()(window).scrollTop(-t))}},{key:"open",value:function(){var t=this,e="#".concat(this.id);this.options.deepLink&&window.location.hash!==e&&(window.history.pushState?this.options.updateHistory?window.history.pushState({},"",e):window.history.replaceState({},"",e):window.location.hash=e),this.$activeAnchor=o()(document.activeElement).is(this.$anchor)?o()(document.activeElement):this.$anchor,this.isActive=!0,this.$element.css({visibility:"hidden"}).show().scrollTop(0),this.options.overlay&&this.$overlay.css({visibility:"hidden"}).show(),this._updatePosition(),this.$element.hide().css({visibility:""}),this.$overlay&&(this.$overlay.css({visibility:""}).hide(),this.$element.hasClass("fast")?this.$overlay.addClass("fast"):this.$element.hasClass("slow")&&this.$overlay.addClass("slow")),this.options.multipleOpened||this.$element.trigger("closeme.zf.reveal",this.id),0===o()(".reveal:visible").length&&this._disableScroll();var n=this;this.options.animationIn?(this.options.overlay&&u.Motion.animateIn(this.$overlay,"fade-in"),u.Motion.animateIn(this.$element,this.options.animationIn,(function(){t.$element&&(t.focusableElements=a.Keyboard.findFocusable(t.$element),n.$element.attr({"aria-hidden":!1,tabindex:-1}).focus(),n._addGlobalClasses(),a.Keyboard.trapFocus(n.$element))}))):(this.options.overlay&&this.$overlay.show(0),this.$element.show(this.options.showDelay)),this.$element.attr({"aria-hidden":!1,tabindex:-1}).focus(),a.Keyboard.trapFocus(this.$element),this._addGlobalClasses(),this._addGlobalListeners(),this.$element.trigger("open.zf.reveal")}},{key:"_addGlobalClasses",value:function(){var t=function(){o()("html").toggleClass("zf-has-scroll",!!(o()(document).height()>o()(window).height()))};this.$element.on("resizeme.zf.trigger.revealScrollbarListener",(function(){return t()})),t(),o()("html").addClass("is-reveal-open")}},{key:"_removeGlobalClasses",value:function(){this.$element.off("resizeme.zf.trigger.revealScrollbarListener"),o()("html").removeClass("is-reveal-open"),o()("html").removeClass("zf-has-scroll")}},{key:"_addGlobalListeners",value:function(){var t=this;this.$element&&(this.focusableElements=a.Keyboard.findFocusable(this.$element),this.options.overlay||!this.options.closeOnClick||this.options.fullScreen||o()("body").on("click.zf.dropdown tap.zf.dropdown",(function(e){e.target!==t.$element[0]&&!o().contains(t.$element[0],e.target)&&o().contains(document,e.target)&&t.close()})),this.options.closeOnEsc&&o()(window).on("keydown.zf.reveal",(function(e){a.Keyboard.handleKey(e,"Reveal",{close:function(){t.options.closeOnEsc&&t.close()}})})))}},{key:"close",value:function(){if(!this.isActive||!this.$element.is(":visible"))return!1;var t=this;function e(){var e=parseInt(o()("html").css("top"),10);0===o()(".reveal:visible").length&&t._removeGlobalClasses(),a.Keyboard.releaseFocus(t.$element),t.$element.attr("aria-hidden",!0),0===o()(".reveal:visible").length&&t._enableScroll(e),t.$element.trigger("closed.zf.reveal")}if(this.options.animationOut?(this.options.overlay&&u.Motion.animateOut(this.$overlay,"fade-out"),u.Motion.animateOut(this.$element,this.options.animationOut,e)):(this.$element.hide(this.options.hideDelay),this.options.overlay?this.$overlay.hide(0,e):e()),this.options.closeOnEsc&&o()(window).off("keydown.zf.reveal"),!this.options.overlay&&this.options.closeOnClick&&o()("body").off("click.zf.dropdown tap.zf.dropdown"),this.$element.off("keydown.zf.reveal"),this.options.resetOnClose&&this.$element.html(this.$element.html()),this.isActive=!1,t.options.deepLink&&window.location.hash==="#".concat(this.id))if(window.history.replaceState){var n=window.location.pathname+window.location.search;this.options.updateHistory?window.history.pushState({},"",n):window.history.replaceState("",document.title,n)}else window.location.hash="";this.$activeAnchor.focus()}},{key:"toggle",value:function(){this.isActive?this.close():this.open()}},{key:"_destroy",value:function(){this.options.overlay&&(this.$element.appendTo(o()(this.options.appendTo)),this.$overlay.hide().off().remove()),this.$element.hide().off(),this.$anchor.off(".zf"),o()(window).off(".zf.reveal:".concat(this.id)),this.onLoadListener&&o()(window).off(this.onLoadListener),0===o()(".reveal:visible").length&&this._removeGlobalClasses()}}])&&h(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),g}(r.Plugin);m.defaults={animationIn:"",animationOut:"",showDelay:0,hideDelay:0,closeOnClick:!0,closeOnEsc:!0,multipleOpened:!1,vOffset:"auto",hOffset:"auto",fullScreen:!1,overlay:!0,resetOnClose:!1,deepLink:!1,updateHistory:!1,appendTo:"body",additionalOverlayClasses:""}},"./js/foundation.slider.js":function(t,e,n){n.r(e),n.d(e,{Slider:function(){return v}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.keyboard.js"),s=n("./js/foundation.util.motion.js"),a=n("./js/foundation.core.utils.js"),l=n("./js/foundation.core.plugin.js"),u=n("./js/foundation.util.touch.js"),c=n("./js/foundation.util.triggers.js");function f(t){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},f(t)}function d(t,e){for(var n=0;n1?this.inputs.eq(1):o()("#".concat(this.$handle2.attr("aria-controls"))),this.inputs[1]||(this.inputs=this.inputs.add(this.$input2)),this._setInitAttr(1)),this.setHandles(),this._events(),this.initialized=!0}},{key:"setHandles",value:function(){var t=this;this.handles[1]?this._setHandlePos(this.$handle,this.inputs.eq(0).val(),(function(){t._setHandlePos(t.$handle2,t.inputs.eq(1).val())})):this._setHandlePos(this.$handle,this.inputs.eq(0).val())}},{key:"_reflow",value:function(){this.setHandles()}},{key:"_pctOfBar",value:function(t){var e=m(t-this.options.start,this.options.end-this.options.start);switch(this.options.positionValueFunction){case"pow":e=this._logTransform(e);break;case"log":e=this._powTransform(e)}return e.toFixed(2)}},{key:"_value",value:function(t){switch(this.options.positionValueFunction){case"pow":t=this._powTransform(t);break;case"log":t=this._logTransform(t)}return this.options.vertical?parseFloat(this.options.end)+t*(this.options.start-this.options.end):(this.options.end-this.options.start)*t+parseFloat(this.options.start)}},{key:"_logTransform",value:function(t){return function(t,e){return Math.log(e)/Math.log(t)}(this.options.nonLinearBase,t*(this.options.nonLinearBase-1)+1)}},{key:"_powTransform",value:function(t){return(Math.pow(this.options.nonLinearBase,t)-1)/(this.options.nonLinearBase-1)}},{key:"_setHandlePos",value:function(t,e,n){if(!this.$element.hasClass(this.options.disabledClass)){(e=parseFloat(e))this.options.end&&(e=this.options.end);var i=this.options.doubleSided;if(i)if(0===this.handles.index(t)){var o=parseFloat(this.$handle2.attr("aria-valuenow"));e=e>=o?o-this.options.step:e}else{var r=parseFloat(this.$handle.attr("aria-valuenow"));e=e<=r?r+this.options.step:e}var a=this,l=this.options.vertical,u=l?"height":"width",c=l?"top":"left",f=t[0].getBoundingClientRect()[u],d=this.$element[0].getBoundingClientRect()[u],h=this._pctOfBar(e),p=(100*m((d-f)*h,d)).toFixed(this.options.decimal);e=parseFloat(e.toFixed(this.options.decimal));var v={};if(this._setValues(t,e),i){var g,y=0===this.handles.index(t),b=Math.floor(100*m(f,d));if(y)v[c]="".concat(p,"%"),g=parseFloat(this.$handle2[0].style[c])-p+b,n&&"function"==typeof n&&n();else{var w=parseFloat(this.$handle[0].style[c]);g=p-(isNaN(w)?(this.options.initialStart-this.options.start)/((this.options.end-this.options.start)/100):w)+b}v["min-".concat(u)]="".concat(g,"%")}var k=this.$element.data("dragging")?1e3/60:this.options.moveTime;(0,s.Move)(k,t,(function(){isNaN(p)?t.css(c,"".concat(100*h,"%")):t.css(c,"".concat(p,"%")),a.options.doubleSided?a.$fill.css(v):a.$fill.css(u,"".concat(100*h,"%"))})),this.initialized&&(this.$element.one("finished.zf.animate",(function(){a.$element.trigger("moved.zf.slider",[t])})),clearTimeout(a.timeout),a.timeout=setTimeout((function(){a.$element.trigger("changed.zf.slider",[t])}),a.options.changedDelay))}}},{key:"_setInitAttr",value:function(t){var e=0===t?this.options.initialStart:this.options.initialEnd,n=this.inputs.eq(t).attr("id")||(0,a.GetYoDigits)(6,"slider");this.inputs.eq(t).attr({id:n,max:this.options.end,min:this.options.start,step:this.options.step}),this.inputs.eq(t).val(e),this.handles.eq(t).attr({role:"slider","aria-controls":n,"aria-valuemax":this.options.end,"aria-valuemin":this.options.start,"aria-valuenow":e,"aria-orientation":this.options.vertical?"vertical":"horizontal",tabindex:0})}},{key:"_setValues",value:function(t,e){var n=this.options.doubleSided?this.handles.index(t):0;this.inputs.eq(n).val(e),t.attr("aria-valuenow",e)}},{key:"_handleEvent",value:function(t,e,n){var i;if(n)i=this._adjustValue(null,n);else{t.preventDefault();var r=this.options.vertical,s=r?"height":"width",l=r?"top":"left",u=r?t.pageY:t.pageX,c=this.$element[0].getBoundingClientRect()[s],f=r?o()(window).scrollTop():o()(window).scrollLeft(),d=this.$element.offset()[l];t.clientY===t.pageY&&(u+=f);var h,p=u-d,v=m(h=p<0?0:p>c?c:p,c);i=this._value(v),(0,a.rtl)()&&!this.options.vertical&&(i=this.options.end-i),i=this._adjustValue(null,i),e||(e=g(this.$handle,l,h,s)<=g(this.$handle2,l,h,s)?this.$handle:this.$handle2)}this._setHandlePos(e,i)}},{key:"_adjustValue",value:function(t,e){var n,i,o,r=this.options.step,s=parseFloat(r/2);return 0===(i=(n=t?parseFloat(t.attr("aria-valuenow")):e)>=0?n%r:r+n%r)?n:n=n>=(o=n-i)+s?o+r:o}},{key:"_events",value:function(){this._eventsForHandle(this.$handle),this.handles[1]&&this._eventsForHandle(this.$handle2)}},{key:"_eventsForHandle",value:function(t){var e,n=this,i=function(t){var e=n.inputs.index(o()(this));n._handleEvent(t,n.handles.eq(e),o()(this).val())};if(this.inputs.off("keyup.zf.slider").on("keyup.zf.slider",(function(t){13===t.keyCode&&i.call(this,t)})),this.inputs.off("change.zf.slider").on("change.zf.slider",i),this.options.clickSelect&&this.$element.off("click.zf.slider").on("click.zf.slider",(function(t){if(n.$element.data("dragging"))return!1;o()(t.target).is("[data-slider-handle]")||(n.options.doubleSided?n._handleEvent(t):n._handleEvent(t,n.$handle))})),this.options.draggable){this.handles.addTouch();var s=o()("body");t.off("mousedown.zf.slider").on("mousedown.zf.slider",(function(i){t.addClass("is-dragging"),n.$fill.addClass("is-dragging"),n.$element.data("dragging",!0),e=o()(i.currentTarget),s.on("mousemove.zf.slider",(function(t){t.preventDefault(),n._handleEvent(t,e)})).on("mouseup.zf.slider",(function(i){n._handleEvent(i,e),t.removeClass("is-dragging"),n.$fill.removeClass("is-dragging"),n.$element.data("dragging",!1),s.off("mousemove.zf.slider mouseup.zf.slider")}))})).on("selectstart.zf.slider touchmove.zf.slider",(function(t){t.preventDefault()}))}t.off("keydown.zf.slider").on("keydown.zf.slider",(function(e){var i,s=o()(this),a=(n.options.doubleSided&&n.handles.index(s),parseFloat(t.attr("aria-valuenow")));r.Keyboard.handleKey(e,"Slider",{decrease:function(){i=a-n.options.step},increase:function(){i=a+n.options.step},decreaseFast:function(){i=a-10*n.options.step},increaseFast:function(){i=a+10*n.options.step},min:function(){i=n.options.start},max:function(){i=n.options.end},handled:function(){e.preventDefault(),n._setHandlePos(s,i)}})}))}},{key:"_destroy",value:function(){this.handles.off(".zf.slider"),this.inputs.off(".zf.slider"),this.$element.off(".zf.slider"),clearTimeout(this.timeout)}}])&&d(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),y}(l.Plugin);function m(t,e){return t/e}function g(t,e,n,i){return Math.abs(t.position()[e]+t[i]()/2-n)}v.defaults={start:0,end:100,step:1,initialStart:0,initialEnd:100,binding:!1,clickSelect:!0,vertical:!1,draggable:!0,disabled:!1,doubleSided:!1,decimal:2,moveTime:200,disabledClass:"disabled",invertVertical:!1,changedDelay:500,nonLinearBase:5,positionValueFunction:"linear"}},"./js/foundation.smoothScroll.js":function(t,e,n){n.r(e),n.d(e,{SmoothScroll:function(){return c}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.utils.js");function s(t){return s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},s(t)}function a(t,e){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:h.defaults,n=arguments.length>2?arguments[2]:void 0,i=o()(t);if(!i.length)return!1;var r=Math.round(i.offset().top-e.threshold/2-e.offset);o()("html, body").stop(!0).animate({scrollTop:r},e.animationDuration,e.animationEasing,(function(){"function"==typeof n&&n()}))}}],(n=[{key:"_setup",value:function(t,e){this.$element=t,this.options=o().extend({},h.defaults,this.$element.data(),e),this.className="SmoothScroll",this._init()}},{key:"_init",value:function(){var t=this.$element[0].id||(0,r.GetYoDigits)(6,"smooth-scroll");this.$element.attr({id:t}),this._events()}},{key:"_events",value:function(){this._linkClickListener=this._handleLinkClick.bind(this),this.$element.on("click.zf.smoothScroll",this._linkClickListener),this.$element.on("click.zf.smoothScroll",'a[href^="#"]',this._linkClickListener)}},{key:"_handleLinkClick",value:function(t){var e=this;if(o()(t.currentTarget).is('a[href^="#"]')){var n=t.currentTarget.getAttribute("href");this._inTransition=!0,h.scrollToLoc(n,this.options,(function(){e._inTransition=!1})),t.preventDefault()}}},{key:"_destroy",value:function(){this.$element.off("click.zf.smoothScroll",this._linkClickListener),this.$element.off("click.zf.smoothScroll",'a[href^="#"]',this._linkClickListener)}}])&&a(e.prototype,n),i&&a(e,i),Object.defineProperty(e,"prototype",{writable:!1}),h}(n("./js/foundation.core.plugin.js").Plugin);c.defaults={animationDuration:500,animationEasing:"linear",threshold:50,offset:0}},"./js/foundation.sticky.js":function(t,e,n){n.r(e),n.d(e,{Sticky:function(){return h}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.plugin.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.util.mediaQuery.js"),l=n("./js/foundation.util.triggers.js");function u(t){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}function c(t,e){for(var n=0;n=n.topPoint))})),n._events(e.split("-").reverse().join("-"))}))}},{key:"_parsePoints",value:function(){for(var t=[""===this.options.topAnchor?1:this.options.topAnchor,""===this.options.btmAnchor?document.documentElement.scrollHeight:this.options.btmAnchor],e={},n=0,i=t.length;n=this.topPoint?e<=this.bottomPoint?this.isStuck||this._setSticky():this.isStuck&&this._removeSticky(!1):this.isStuck&&this._removeSticky(!0)}},{key:"_setSticky",value:function(){var t=this,e=this.options.stickTo,n="top"===e?"marginTop":"marginBottom",i="top"===e?"bottom":"top",o={};o[n]="".concat(this.options[n],"em"),o[e]=0,o[i]="auto",this.isStuck=!0,this.$element.removeClass("is-anchored is-at-".concat(i)).addClass("is-stuck is-at-".concat(e)).css(o).trigger("sticky.zf.stuckto:".concat(e)),this.$element.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd",(function(){t._setSizes()}))}},{key:"_removeSticky",value:function(t){var e=this.options.stickTo,n="top"===e,i={},o=(this.points?this.points[1]-this.points[0]:this.anchorHeight)-this.elemHeight,r=t?"top":"bottom";i[n?"marginTop":"marginBottom"]=0,i.bottom="auto",i.top=t?0:o,this.isStuck=!1,this.$element.removeClass("is-stuck is-at-".concat(e)).addClass("is-anchored is-at-".concat(r)).css(i).trigger("sticky.zf.unstuckfrom:".concat(r))}},{key:"_setSizes",value:function(t){this.canStick=a.MediaQuery.is(this.options.stickyOn),this.canStick||t&&"function"==typeof t&&t();var e=this.$container[0].getBoundingClientRect().width,n=window.getComputedStyle(this.$container[0]),i=parseInt(n["padding-left"],10),o=parseInt(n["padding-right"],10);if(this.$anchor&&this.$anchor.length?this.anchorHeight=this.$anchor[0].getBoundingClientRect().height:this._parsePoints(),this.$element.css({"max-width":"".concat(e-i-o,"px")}),this.options.dynamicHeight||!this.containerHeight){var r=this.$element[0].getBoundingClientRect().height||this.containerHeight;r="none"===this.$element.css("display")?0:r,this.$container.css("height",r),this.containerHeight=r}if(this.elemHeight=this.containerHeight,!this.isStuck&&this.$element.hasClass("is-at-bottom")){var s=(this.points?this.points[1]-this.$container.offset().top:this.anchorHeight)-this.elemHeight;this.$element.css("top",s)}this._setBreakPoints(this.containerHeight,(function(){t&&"function"==typeof t&&t()}))}},{key:"_setBreakPoints",value:function(t,e){if(!this.canStick){if(!e||"function"!=typeof e)return!1;e()}var n=p(this.options.marginTop),i=p(this.options.marginBottom),o=this.points?this.points[0]:this.$anchor.offset().top,r=this.points?this.points[1]:o+this.anchorHeight,s=window.innerHeight;"top"===this.options.stickTo?(o-=n,r-=t+n):"bottom"===this.options.stickTo&&(o-=s-(t+i),r-=s-i),this.topPoint=o,this.bottomPoint=r,e&&"function"==typeof e&&e()}},{key:"_destroy",value:function(){this._removeSticky(!0),this.$element.removeClass("".concat(this.options.stickyClass," is-anchored is-at-top")).css({height:"",top:"",bottom:"","max-width":""}).off("resizeme.zf.trigger").off("mutateme.zf.trigger"),this.$anchor&&this.$anchor.length&&this.$anchor.off("change.zf.sticky"),this.scrollListener&&o()(window).off(this.scrollListener),this.onLoadListener&&o()(window).off(this.onLoadListener),this.wasWrapped?this.$element.unwrap():this.$container.removeClass(this.options.containerClass).css({height:""})}}])&&c(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),v}(r.Plugin);function p(t){return parseInt(window.getComputedStyle(document.body,null).fontSize,10)*t}h.defaults={container:"
      ",stickTo:"top",anchor:"",topAnchor:"",btmAnchor:"",marginTop:1,marginBottom:1,stickyOn:"medium",stickyClass:"sticky",containerClass:"sticky-container",dynamicHeight:!0,checkEvery:-1}},"./js/foundation.tabs.js":function(t,e,n){n.r(e),n.d(e,{Tabs:function(){return h}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.plugin.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.util.keyboard.js"),l=n("./js/foundation.util.imageLoader.js");function u(t){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}function c(t,e){for(var n=0;n=0?e.slice(1):e,i=n&&o()("#".concat(n)),r=e&&t.$element.find('[href$="'.concat(e,'"],[data-tabs-target="').concat(n,'"]')).first();if(i.length&&r.length){if(i&&i.length&&r&&r.length?t.selectTab(i,!0):t._collapse(),t.options.deepLinkSmudge){var s=t.$element.offset();o()("html, body").animate({scrollTop:s.top-t.options.deepLinkSmudgeOffset},t.options.deepLinkSmudgeDelay)}t.$element.trigger("deeplink.zf.tabs",[r,i])}},this.options.deepLink&&this._checkDeepLink(),this._events(),this._isInitializing=!1}},{key:"_events",value:function(){this._addKeyHandler(),this._addClickHandler(),this._setHeightMqHandler=null,this.options.matchHeight&&(this._setHeightMqHandler=this._setHeight.bind(this),o()(window).on("changed.zf.mediaquery",this._setHeightMqHandler)),this.options.deepLink&&o()(window).on("hashchange",this._checkDeepLink)}},{key:"_addClickHandler",value:function(){var t=this;this.$element.off("click.zf.tabs").on("click.zf.tabs",".".concat(this.options.linkClass),(function(e){e.preventDefault(),t._handleTabChange(o()(this))}))}},{key:"_addKeyHandler",value:function(){var t=this;this.$tabTitles.off("keydown.zf.tabs").on("keydown.zf.tabs",(function(e){if(9!==e.which){var n,i,r=o()(this),s=r.parent("ul").children("li");s.each((function(e){o()(this).is(r)&&(t.options.wrapOnKeys?(n=0===e?s.last():s.eq(e-1),i=e===s.length-1?s.first():s.eq(e+1)):(n=s.eq(Math.max(0,e-1)),i=s.eq(Math.min(e+1,s.length-1))))})),a.Keyboard.handleKey(e,"Tabs",{open:function(){r.find('[role="tab"]').focus(),t._handleTabChange(r)},previous:function(){n.find('[role="tab"]').focus(),t._handleTabChange(n)},next:function(){i.find('[role="tab"]').focus(),t._handleTabChange(i)},handled:function(){e.preventDefault()}})}}))}},{key:"_handleTabChange",value:function(t,e){if(t.hasClass("".concat(this.options.linkActiveClass)))this.options.activeCollapse&&this._collapse();else{var n=this.$element.find(".".concat(this.options.linkClass,".").concat(this.options.linkActiveClass)),i=t.find('[role="tab"]'),o=i.attr("data-tabs-target"),r=o&&o.length?"#".concat(o):i[0].hash,s=this.$tabContent.find(r);this._collapseTab(n),this._openTab(t),this.options.deepLink&&!e&&(this.options.updateHistory?history.pushState({},"",r):history.replaceState({},"",r)),this.$element.trigger("change.zf.tabs",[t,s]),s.find("[data-mutate]").trigger("mutateme.zf.trigger")}}},{key:"_openTab",value:function(t){var e=t.find('[role="tab"]'),n=e.attr("data-tabs-target")||e[0].hash.slice(1),i=this.$tabContent.find("#".concat(n));t.addClass("".concat(this.options.linkActiveClass)),e.attr({"aria-selected":"true",tabindex:"0"}),i.addClass("".concat(this.options.panelActiveClass)).removeAttr("aria-hidden")}},{key:"_collapseTab",value:function(t){var e=t.removeClass("".concat(this.options.linkActiveClass)).find('[role="tab"]').attr({"aria-selected":"false",tabindex:-1});o()("#".concat(e.attr("aria-controls"))).removeClass("".concat(this.options.panelActiveClass)).attr({"aria-hidden":"true"})}},{key:"_collapse",value:function(){var t=this.$element.find(".".concat(this.options.linkClass,".").concat(this.options.linkActiveClass));t.length&&(this._collapseTab(t),this.$element.trigger("collapse.zf.tabs",[t]))}},{key:"selectTab",value:function(t,e){var n,i;(n="object"===u(t)?t[0].id:t).indexOf("#")<0?i="#".concat(n):(i=n,n=n.slice(1));var o=this.$tabTitles.has('[href$="'.concat(i,'"],[data-tabs-target="').concat(n,'"]')).first();this._handleTabChange(o,e)}},{key:"_setHeight",value:function(){var t=0,e=this;this.$tabContent&&this.$tabContent.find(".".concat(this.options.panelClass)).css("min-height","").each((function(){var n=o()(this),i=n.hasClass("".concat(e.options.panelActiveClass));i||n.css({visibility:"hidden",display:"block"});var r=this.getBoundingClientRect().height;i||n.css({visibility:"",display:""}),t=r>t?r:t})).css("min-height","".concat(t,"px"))}},{key:"_destroy",value:function(){this.$element.find(".".concat(this.options.linkClass)).off(".zf.tabs").hide().end().find(".".concat(this.options.panelClass)).hide(),this.options.matchHeight&&null!=this._setHeightMqHandler&&o()(window).off("changed.zf.mediaquery",this._setHeightMqHandler),this.options.deepLink&&o()(window).off("hashchange",this._checkDeepLink),this.onLoadListener&&o()(window).off(this.onLoadListener)}}])&&c(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),p}(r.Plugin);h.defaults={deepLink:!1,deepLinkSmudge:!1,deepLinkSmudgeDelay:300,deepLinkSmudgeOffset:0,updateHistory:!1,autoFocus:!1,wrapOnKeys:!0,matchHeight:!1,activeCollapse:!1,linkClass:"tabs-title",linkActiveClass:"is-active",panelClass:"tabs-panel",panelActiveClass:"is-active"}},"./js/foundation.toggler.js":function(t,e,n){n.r(e),n.d(e,{Toggler:function(){return h}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.motion.js"),s=n("./js/foundation.core.plugin.js"),a=n("./js/foundation.core.utils.js"),l=n("./js/foundation.util.triggers.js");function u(t){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}function c(t,e){for(var n=0;n").addClass(e).attr({role:"tooltip","aria-hidden":!0,"data-is-active":!1,"data-is-focus":!1,id:t})}},{key:"_setPosition",value:function(){c(d(v.prototype),"_setPosition",this).call(this,this.$element,this.template)}},{key:"show",value:function(){if("all"!==this.options.showOn&&!s.MediaQuery.is(this.options.showOn))return!1;this.template.css("visibility","hidden").show(),this._setPosition(),this.template.removeClass("top bottom left right").addClass(this.position),this.template.removeClass("align-top align-bottom align-left align-right align-center").addClass("align-"+this.alignment),this.$element.trigger("closeme.zf.tooltip",this.template.attr("id")),this.template.attr({"data-is-active":!0,"aria-hidden":!1}),this.isActive=!0,this.template.stop().hide().css("visibility","").fadeIn(this.options.fadeInDuration,(function(){})),this.$element.trigger("show.zf.tooltip")}},{key:"hide",value:function(){var t=this;this.template.stop().attr({"aria-hidden":!0,"data-is-active":!1}).fadeOut(this.options.fadeOutDuration,(function(){t.isActive=!1,t.isClick=!1})),this.$element.trigger("hide.zf.tooltip")}},{key:"_events",value:function(){var t=this,e="ontouchstart"in window||void 0!==window.ontouchstart,n=!1;e&&this.options.disableForTouch||(this.options.disableHover||this.$element.on("mouseenter.zf.tooltip",(function(){t.isActive||(t.timeout=setTimeout((function(){t.show()}),t.options.hoverDelay))})).on("mouseleave.zf.tooltip",(0,r.ignoreMousedisappear)((function(){clearTimeout(t.timeout),(!n||t.isClick&&!t.options.clickOpen)&&t.hide()}))),e&&this.$element.on("tap.zf.tooltip touchend.zf.tooltip",(function(){t.isActive?t.hide():t.show()})),this.options.clickOpen?this.$element.on("mousedown.zf.tooltip",(function(){t.isClick||(t.isClick=!0,!t.options.disableHover&&t.$element.attr("tabindex")||t.isActive||t.show())})):this.$element.on("mousedown.zf.tooltip",(function(){t.isClick=!0})),this.$element.on({"close.zf.trigger":this.hide.bind(this)}),this.$element.on("focus.zf.tooltip",(function(){if(n=!0,t.isClick)return t.options.clickOpen||(n=!1),!1;t.show()})).on("focusout.zf.tooltip",(function(){n=!1,t.isClick=!1,t.hide()})).on("resizeme.zf.trigger",(function(){t.isActive&&t._setPosition()})))}},{key:"toggle",value:function(){this.isActive?this.hide():this.show()}},{key:"_destroy",value:function(){this.$element.attr("title",this.template.text()).off(".zf.trigger .zf.tooltip").removeClass(this.options.triggerClass).removeClass("top right left bottom").removeAttr("aria-describedby data-disable-hover data-resize data-toggle data-tooltip data-yeti-box"),this.template.remove()}}])&&u(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),v}(n("./js/foundation.positionable.js").Positionable);h.defaults={hoverDelay:200,fadeInDuration:150,fadeOutDuration:150,disableHover:!1,disableForTouch:!1,templateClasses:"",tooltipClass:"tooltip",triggerClass:"has-tip",showOn:"small",template:"",tipText:"",touchCloseText:"Tap to close.",clickOpen:!0,position:"auto",alignment:"auto",allowOverlap:!1,allowBottomOverlap:!1,vOffset:0,hOffset:0,tooltipHeight:14,tooltipWidth:12,allowHtml:!1}},"./js/foundation.util.box.js":function(t,e,n){n.r(e),n.d(e,{Box:function(){return i}});var i={ImNotTouchingYou:function(t,e,n,i,r){return 0===o(t,e,n,i,r)},OverlapArea:o,GetDimensions:r,GetExplicitOffsets:function(t,e,n,i,o,s,a){var l,u,c=r(t),f=e?r(e):null;if(null!==f){switch(n){case"top":l=f.offset.top-(c.height+o);break;case"bottom":l=f.offset.top+f.height+o;break;case"left":u=f.offset.left-(c.width+s);break;case"right":u=f.offset.left+f.width+s}switch(n){case"top":case"bottom":switch(i){case"left":u=f.offset.left+s;break;case"right":u=f.offset.left-c.width+f.width-s;break;case"center":u=a?s:f.offset.left+f.width/2-c.width/2+s}break;case"right":case"left":switch(i){case"bottom":l=f.offset.top-o+f.height-c.height;break;case"top":l=f.offset.top+o;break;case"center":l=f.offset.top+o+f.height/2-c.height/2}}}return{top:l,left:u}}};function o(t,e,n,i,o){var s,a,l,u,c=r(t);if(e){var f=r(e);a=f.height+f.offset.top-(c.offset.top+c.height),s=c.offset.top-f.offset.top,l=c.offset.left-f.offset.left,u=f.width+f.offset.left-(c.offset.left+c.width)}else a=c.windowDims.height+c.windowDims.offset.top-(c.offset.top+c.height),s=c.offset.top-c.windowDims.offset.top,l=c.offset.left-c.windowDims.offset.left,u=c.windowDims.width-(c.offset.left+c.width);return a=o?0:Math.min(a,0),s=Math.min(s,0),l=Math.min(l,0),u=Math.min(u,0),n?l+u:i?s+a:Math.sqrt(s*s+a*a+l*l+u*u)}function r(t){if((t=t.length?t[0]:t)===window||t===document)throw new Error("I'm sorry, Dave. I'm afraid I can't do that.");var e=t.getBoundingClientRect(),n=t.parentNode.getBoundingClientRect(),i=document.body.getBoundingClientRect(),o=window.pageYOffset,r=window.pageXOffset;return{width:e.width,height:e.height,offset:{top:e.top+o,left:e.left+r},parentDims:{width:n.width,height:n.height,offset:{top:n.top+o,left:n.left+r}},windowDims:{width:i.width,height:i.height,offset:{top:o,left:r}}}}},"./js/foundation.util.imageLoader.js":function(t,e,n){n.r(e),n.d(e,{onImagesLoaded:function(){return r}});var i=n("jquery"),o=n.n(i);function r(t,e){var n=t.length;function i(){0==--n&&e()}0===n&&e(),t.each((function(){if(this.complete&&void 0!==this.naturalWidth)i();else{var t=new Image,e="load.zf.images error.zf.images";o()(t).one(e,(function t(){o()(this).off(e,t),i()})),t.src=o()(this).attr("src")}}))}},"./js/foundation.util.keyboard.js":function(t,e,n){n.r(e),n.d(e,{Keyboard:function(){return c}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.utils.js"),s={9:"TAB",13:"ENTER",27:"ESCAPE",32:"SPACE",35:"END",36:"HOME",37:"ARROW_LEFT",38:"ARROW_UP",39:"ARROW_RIGHT",40:"ARROW_DOWN"},a={};function l(t){return!!t&&t.find("a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]").filter((function(){return!(!o()(this).is(":visible")||o()(this).attr("tabindex")<0)})).sort((function(t,e){if(o()(t).attr("tabindex")===o()(e).attr("tabindex"))return 0;var n=parseInt(o()(t).attr("tabindex"),10),i=parseInt(o()(e).attr("tabindex"),10);return void 0===o()(t).attr("tabindex")&&i>0?1:void 0===o()(e).attr("tabindex")&&n>0?-1:0===n&&i>0?1:0===i&&n>0||ni?1:void 0}))}function u(t){var e=s[t.which||t.keyCode]||String.fromCharCode(t.which).toUpperCase();return e=e.replace(/\W+/,""),t.shiftKey&&(e="SHIFT_".concat(e)),t.ctrlKey&&(e="CTRL_".concat(e)),t.altKey&&(e="ALT_".concat(e)),e.replace(/_$/,"")}var c={keys:function(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[t[n]]=t[n]);return e}(s),parseKey:u,handleKey:function(t,e,n){var i,s=a[e],l=this.parseKey(t);if(!s)return console.warn("Component not defined!");if(!0!==t.zfIsKeyHandled)if((i=n[(void 0===s.ltr?s:(0,r.rtl)()?o().extend({},s.ltr,s.rtl):o().extend({},s.rtl,s.ltr))[l]])&&"function"==typeof i){var u=i.apply();t.zfIsKeyHandled=!0,(n.handled||"function"==typeof n.handled)&&n.handled(u)}else(n.unhandled||"function"==typeof n.unhandled)&&n.unhandled()},findFocusable:l,register:function(t,e){a[t]=e},trapFocus:function(t){var e=l(t),n=e.eq(0),i=e.eq(-1);t.on("keydown.zf.trapfocus",(function(t){t.target===i[0]&&"TAB"===u(t)?(t.preventDefault(),n.focus()):t.target===n[0]&&"SHIFT_TAB"===u(t)&&(t.preventDefault(),i.focus())}))},releaseFocus:function(t){t.off("keydown.zf.trapfocus")}}},"./js/foundation.util.mediaQuery.js":function(t,e,n){n.r(e),n.d(e,{MediaQuery:function(){return a}});var i=n("jquery"),o=n.n(i);function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function s(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,i=new Array(e);n').appendTo(document.head);var t,e,n,i=o()(".foundation-mq").css("font-family");for(var r in n=void 0,n={},t="string"!=typeof(e=i)?n:(e=e.trim().slice(1,-1))?(n=e.split("&").reduce((function(t,e){var n=e.replace(/\+/g," ").split("="),i=n[0],o=n[1];return i=decodeURIComponent(i),o=void 0===o?null:decodeURIComponent(o),t.hasOwnProperty(i)?Array.isArray(t[i])?t[i].push(o):t[i]=[t[i],o]:t[i]=o,t}),{}),n):n,this.queries=[],t)t.hasOwnProperty(r)&&this.queries.push({name:r,value:"only screen and (min-width: ".concat(t[r],")")});this.current=this._getCurrentSize(),this._watcher()},_reInit:function(){this.isInitialized=!1,this._init()},atLeast:function(t){var e=this.get(t);return!!e&&window.matchMedia(e).matches},only:function(t){return t===this._getCurrentSize()},upTo:function(t){var e=this.next(t);return!e||!this.atLeast(e)},is:function(t){var e,n,i=(e=t.trim().split(" ").filter((function(t){return!!t.length})),n=2,function(t){if(Array.isArray(t))return t}(e)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){var i,o,r,s,a=[],l=!0,u=!1;try{if(r=(n=n.call(t)).next,0===e){if(Object(n)!==n)return;l=!1}else for(;!(l=(i=r.call(n)).done)&&(a.push(i.value),a.length!==e);l=!0);}catch(t){u=!0,o=t}finally{try{if(!l&&null!=n.return&&(s=n.return(),Object(s)!==s))return}finally{if(u)throw o}}return a}}(e,n)||function(t,e){if(t){if("string"==typeof t)return s(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(t,e):void 0}}(e,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),o=i[0],r=i[1],a=void 0===r?"":r;if("only"===a)return this.only(o);if(!a||"up"===a)return this.atLeast(o);if("down"===a)return this.upTo(o);throw new Error('\n Invalid breakpoint passed to MediaQuery.is().\n Expected a breakpoint name formatted like " ", got "'.concat(t,'".\n '))},get:function(t){for(var e in this.queries)if(this.queries.hasOwnProperty(e)){var n=this.queries[e];if(t===n.name)return n.value}return null},next:function(t){var e=this,n=this.queries.findIndex((function(n){return e._getQueryName(n)===t}));if(-1===n)throw new Error('\n Unknown breakpoint "'.concat(t,'" passed to MediaQuery.next().\n Ensure it is present in your Sass "$breakpoints" setting.\n '));var i=this.queries[n+1];return i?i.name:null},_getQueryName:function(t){if("string"==typeof t)return t;if("object"===r(t))return t.name;throw new TypeError('\n Invalid value passed to MediaQuery._getQueryName().\n Expected a breakpoint name (String) or a breakpoint query (Object), got "'.concat(t,'" (').concat(r(t),")\n "))},_getCurrentSize:function(){for(var t,e=0;e1&&void 0!==arguments[1]?arguments[1]:"zf";t.attr("role","menubar"),t.find("a").attr({role:"menuitem"});var n=t.find("li").attr({role:"none"}),i="is-".concat(e,"-submenu"),r="".concat(i,"-item"),s="is-".concat(e,"-submenu-parent"),a="accordion"!==e;n.each((function(){var t=o()(this),n=t.children("ul");if(n.length){if(t.addClass(s),a){var l=t.children("a:first");l.attr({"aria-haspopup":!0,"aria-label":l.attr("aria-label")||l.text()}),"drilldown"===e&&t.attr({"aria-expanded":!1})}n.addClass("submenu ".concat(i)).attr({"data-submenu":"",role:"menubar"}),"drilldown"===e&&n.attr({"aria-hidden":!0})}t.parent("[data-submenu]").length&&t.addClass("is-submenu-item ".concat(r))}))},Burn:function(t,e){var n="is-".concat(e,"-submenu"),i="".concat(n,"-item"),o="is-".concat(e,"-submenu-parent");t.find(">li, > li > ul, .menu, .menu > li, [data-submenu] > li").removeClass("".concat(n," ").concat(i," ").concat(o," is-submenu-item submenu is-active")).removeAttr("data-submenu").css("display","")}}},"./js/foundation.util.timer.js":function(t,e,n){function i(t,e,n){var i,o,r=this,s=e.duration,a=Object.keys(t.data())[0]||"timer",l=-1;this.isPaused=!1,this.restart=function(){l=-1,clearTimeout(o),this.start()},this.start=function(){this.isPaused=!1,clearTimeout(o),l=l<=0?s:l,t.data("paused",!1),i=Date.now(),o=setTimeout((function(){e.infinite&&r.restart(),n&&"function"==typeof n&&n()}),l),t.trigger("timerstart.zf.".concat(a))},this.pause=function(){this.isPaused=!0,clearTimeout(o),t.data("paused",!0);var e=Date.now();l-=e-i,t.trigger("timerpaused.zf.".concat(a))}}n.r(e),n.d(e,{Timer:function(){return i}})},"./js/foundation.util.touch.js":function(t,e,n){n.r(e),n.d(e,{Touch:function(){return f}});var i=n("jquery"),o=n.n(i);function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function s(t,e){for(var n=0;n=o().spotSwipe.moveThreshold&&u<=o().spotSwipe.timeThreshold&&(e=i>0?"left":"right"),e&&(t.preventDefault(),p.apply(this,arguments),o()(this).trigger(o().Event("swipe",Object.assign({},t)),e).trigger(o().Event("swipe".concat(e),Object.assign({},t))))}}function m(t){1===t.touches.length&&(a=t.touches[0].pageX,c=t,d=!0,h=!1,l=(new Date).getTime(),this.addEventListener("touchmove",v,{passive:!0===o().spotSwipe.preventDefault}),this.addEventListener("touchend",p,!1))}function g(){this.addEventListener&&this.addEventListener("touchstart",m,{passive:!0})}var y=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.version="1.0.0",this.enabled="ontouchstart"in document.documentElement,this.preventDefault=!1,this.moveThreshold=75,this.timeThreshold=200,this._init()}var e,n;return e=t,(n=[{key:"_init",value:function(){o().event.special.swipe={setup:g},o().event.special.tap={setup:g},o().each(["left","up","down","right"],(function(){o().event.special["swipe".concat(this)]={setup:function(){o()(this).on("swipe",o().noop)}}}))}}])&&s(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),t}();f.setupSpotSwipe=function(){o().spotSwipe=new y(o())},f.setupTouchHandler=function(){o().fn.addTouch=function(){this.each((function(e,n){o()(n).bind("touchstart touchmove touchend touchcancel",(function(e){t(e)}))}));var t=function(t){var e,n=t.changedTouches[0],i={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup"}[t.type];"MouseEvent"in window&&"function"==typeof window.MouseEvent?e=new window.MouseEvent(i,{bubbles:!0,cancelable:!0,screenX:n.screenX,screenY:n.screenY,clientX:n.clientX,clientY:n.clientY}):(e=document.createEvent("MouseEvent")).initMouseEvent(i,!0,!0,window,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(e)}}},f.init=function(){void 0===o().spotSwipe&&(f.setupSpotSwipe(o()),f.setupTouchHandler(o()))}},"./js/foundation.util.triggers.js":function(t,e,n){n.r(e),n.d(e,{Triggers:function(){return c}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.utils.js"),s=n("./js/foundation.util.motion.js");function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}var l=function(){for(var t=["WebKit","Moz","O","Ms",""],e=0;e0&&e-1 in t)}function O(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()}x.fn=x.prototype={jquery:_,constructor:x,length:0,toArray:function(){return a.call(this)},get:function(t){return null==t?a.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=x.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return x.each(this,t)},map:function(t){return this.pushStack(x.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return this.pushStack(a.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(x.grep(this,(function(t,e){return(e+1)%2})))},odd:function(){return this.pushStack(x.grep(this,(function(t,e){return e%2})))},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n+~]|"+z+")"+z+"*"),F=new RegExp(z+"|>"),N=new RegExp(M),B=new RegExp("^"+A+"$"),W={ID:new RegExp("^#("+A+")"),CLASS:new RegExp("^\\.("+A+")"),TAG:new RegExp("^("+A+"|[*])"),ATTR:new RegExp("^"+R),PSEUDO:new RegExp("^"+M),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+z+"*(even|odd|(([+-]|)(\\d*)n|)"+z+"*(?:([+-]|)"+z+"*(\\d+)|))"+z+"*\\)|)","i"),bool:new RegExp("^(?:"+C+")$","i"),needsContext:new RegExp("^"+z+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+z+"*((?:-\\d)?\\d*)"+z+"*\\)|)(?=[^-]|$)","i")},Q=/^(?:input|select|textarea|button)$/i,G=/^h\d$/i,Y=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,U=new RegExp("\\\\[\\da-fA-F]{1,6}"+z+"?|\\\\([^\\r\\n\\f])","g"),V=function(t,e){var n="0x"+t.slice(1)-65536;return e||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},X=function(){lt()},Z=dt((function(t){return!0===t.disabled&&O(t,"fieldset")}),{dir:"parentNode",next:"legend"});try{v.apply(r=a.call(D.childNodes),D.childNodes),r[D.childNodes.length].nodeType}catch(t){v={apply:function(t,e){L.apply(t,a.call(e))},call:function(t){L.apply(t,a.call(arguments,1))}}}function J(t,e,n,i){var o,r,s,a,u,c,h,p=e&&e.ownerDocument,y=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==y&&9!==y&&11!==y)return n;if(!i&&(lt(e),e=e||l,f)){if(11!==y&&(u=Y.exec(t)))if(o=u[1]){if(9===y){if(!(s=e.getElementById(o)))return n;if(s.id===o)return v.call(n,s),n}else if(p&&(s=p.getElementById(o))&&J.contains(e,s)&&s.id===o)return v.call(n,s),n}else{if(u[2])return v.apply(n,e.getElementsByTagName(t)),n;if((o=u[3])&&e.getElementsByClassName)return v.apply(n,e.getElementsByClassName(o)),n}if(!(_[t+" "]||d&&d.test(t))){if(h=t,p=e,1===y&&(F.test(t)||I.test(t))){for((p=K.test(t)&&at(e.parentNode)||e)==e&&m.scope||((a=e.getAttribute("id"))?a=x.escapeSelector(a):e.setAttribute("id",a=g)),r=(c=ct(t)).length;r--;)c[r]=(a?"#"+a:":scope")+" "+ft(c[r]);h=c.join(",")}try{return v.apply(n,p.querySelectorAll(h)),n}catch(e){_(t,!0)}finally{a===g&&e.removeAttribute("id")}}}return yt(t.replace(P,"$1"),e,n,i)}function tt(){var t=[];return function n(i,o){return t.push(i+" ")>e.cacheLength&&delete n[t.shift()],n[i+" "]=o}}function et(t){return t[g]=!0,t}function nt(t){var e=l.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function it(t){return function(e){return O(e,"input")&&e.type===t}}function ot(t){return function(e){return(O(e,"input")||O(e,"button"))&&e.type===t}}function rt(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&Z(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function st(t){return et((function(e){return e=+e,et((function(n,i){for(var o,r=t([],n.length,e),s=r.length;s--;)n[o=r[s]]&&(n[o]=!(i[o]=n[o]))}))}))}function at(t){return t&&void 0!==t.getElementsByTagName&&t}function lt(t){var n,i=t?t.ownerDocument||t:D;return i!=l&&9===i.nodeType&&i.documentElement?(u=(l=i).documentElement,f=!x.isXMLDoc(l),p=u.matches||u.webkitMatchesSelector||u.msMatchesSelector,u.msMatchesSelector&&D!=l&&(n=l.defaultView)&&n.top!==n&&n.addEventListener("unload",X),m.getById=nt((function(t){return u.appendChild(t).id=x.expando,!l.getElementsByName||!l.getElementsByName(x.expando).length})),m.disconnectedMatch=nt((function(t){return p.call(t,"*")})),m.scope=nt((function(){return l.querySelectorAll(":scope")})),m.cssHas=nt((function(){try{return l.querySelector(":has(*,:jqfake)"),!1}catch(t){return!0}})),m.getById?(e.filter.ID=function(t){var e=t.replace(U,V);return function(t){return t.getAttribute("id")===e}},e.find.ID=function(t,e){if(void 0!==e.getElementById&&f){var n=e.getElementById(t);return n?[n]:[]}}):(e.filter.ID=function(t){var e=t.replace(U,V);return function(t){var n=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}},e.find.ID=function(t,e){if(void 0!==e.getElementById&&f){var n,i,o,r=e.getElementById(t);if(r){if((n=r.getAttributeNode("id"))&&n.value===t)return[r];for(o=e.getElementsByName(t),i=0;r=o[i++];)if((n=r.getAttributeNode("id"))&&n.value===t)return[r]}return[]}}),e.find.TAG=function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):e.querySelectorAll(t)},e.find.CLASS=function(t,e){if(void 0!==e.getElementsByClassName&&f)return e.getElementsByClassName(t)},d=[],nt((function(t){var e;u.appendChild(t).innerHTML="",t.querySelectorAll("[selected]").length||d.push("\\["+z+"*(?:value|"+C+")"),t.querySelectorAll("[id~="+g+"-]").length||d.push("~="),t.querySelectorAll("a#"+g+"+*").length||d.push(".#.+[+~]"),t.querySelectorAll(":checked").length||d.push(":checked"),(e=l.createElement("input")).setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),u.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(e=l.createElement("input")).setAttribute("name",""),t.appendChild(e),t.querySelectorAll("[name='']").length||d.push("\\["+z+"*name"+z+"*="+z+"*(?:''|\"\")")})),m.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),$=function(t,e){if(t===e)return s=!0,0;var n=!t.compareDocumentPosition-!e.compareDocumentPosition;return n||(1&(n=(t.ownerDocument||t)==(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!m.sortDetached&&e.compareDocumentPosition(t)===n?t===l||t.ownerDocument==D&&J.contains(D,t)?-1:e===l||e.ownerDocument==D&&J.contains(D,e)?1:o?c.call(o,t)-c.call(o,e):0:4&n?-1:1)},l):l}for(t in J.matches=function(t,e){return J(t,null,null,e)},J.matchesSelector=function(t,e){if(lt(t),f&&!_[e+" "]&&(!d||!d.test(e)))try{var n=p.call(t,e);if(n||m.disconnectedMatch||t.document&&11!==t.document.nodeType)return n}catch(t){_(e,!0)}return J(e,l,null,[t]).length>0},J.contains=function(t,e){return(t.ownerDocument||t)!=l&<(t),x.contains(t,e)},J.attr=function(t,n){(t.ownerDocument||t)!=l&<(t);var i=e.attrHandle[n.toLowerCase()],o=i&&h.call(e.attrHandle,n.toLowerCase())?i(t,n,!f):void 0;return void 0!==o?o:t.getAttribute(n)},J.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},x.uniqueSort=function(t){var e,n=[],i=0,r=0;if(s=!m.sortStable,o=!m.sortStable&&a.call(t,0),S.call(t,$),s){for(;e=t[r++];)e===t[r]&&(i=n.push(r));for(;i--;)E.call(t,n[i],1)}return o=null,t},x.fn.uniqueSort=function(){return this.pushStack(x.uniqueSort(a.apply(this)))},e=x.expr={cacheLength:50,createPseudo:et,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(U,V),t[3]=(t[3]||t[4]||t[5]||"").replace(U,V),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||J.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&J.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return W.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&N.test(n)&&(e=ct(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(U,V).toLowerCase();return"*"===t?function(){return!0}:function(t){return O(t,e)}},CLASS:function(t){var e=w[t+" "];return e||(e=new RegExp("(^|"+z+")"+t+"("+z+"|$)"))&&w(t,(function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")}))},ATTR:function(t,e,n){return function(i){var o=J.attr(i,t);return null==o?"!="===e:!e||(o+="","="===e?o===n:"!="===e?o!==n:"^="===e?n&&0===o.indexOf(n):"*="===e?n&&o.indexOf(n)>-1:"$="===e?n&&o.slice(-n.length)===n:"~="===e?(" "+o.replace(H," ")+" ").indexOf(n)>-1:"|="===e&&(o===n||o.slice(0,n.length+1)===n+"-"))}},CHILD:function(t,e,n,i,o){var r="nth"!==t.slice(0,3),s="last"!==t.slice(-4),a="of-type"===e;return 1===i&&0===o?function(t){return!!t.parentNode}:function(e,n,l){var u,c,f,d,h,p=r!==s?"nextSibling":"previousSibling",v=e.parentNode,m=a&&e.nodeName.toLowerCase(),b=!l&&!a,w=!1;if(v){if(r){for(;p;){for(f=e;f=f[p];)if(a?O(f,m):1===f.nodeType)return!1;h=p="only"===t&&!h&&"nextSibling"}return!0}if(h=[s?v.firstChild:v.lastChild],s&&b){for(w=(d=(u=(c=v[g]||(v[g]={}))[t]||[])[0]===y&&u[1])&&u[2],f=d&&v.childNodes[d];f=++d&&f&&f[p]||(w=d=0)||h.pop();)if(1===f.nodeType&&++w&&f===e){c[t]=[y,d,w];break}}else if(b&&(w=d=(u=(c=e[g]||(e[g]={}))[t]||[])[0]===y&&u[1]),!1===w)for(;(f=++d&&f&&f[p]||(w=d=0)||h.pop())&&(!(a?O(f,m):1===f.nodeType)||!++w||(b&&((c=f[g]||(f[g]={}))[t]=[y,w]),f!==e)););return(w-=o)===i||w%i==0&&w/i>=0}}},PSEUDO:function(t,n){var i,o=e.pseudos[t]||e.setFilters[t.toLowerCase()]||J.error("unsupported pseudo: "+t);return o[g]?o(n):o.length>1?(i=[t,t,"",n],e.setFilters.hasOwnProperty(t.toLowerCase())?et((function(t,e){for(var i,r=o(t,n),s=r.length;s--;)t[i=c.call(t,r[s])]=!(e[i]=r[s])})):function(t){return o(t,0,i)}):o}},pseudos:{not:et((function(t){var e=[],n=[],i=gt(t.replace(P,"$1"));return i[g]?et((function(t,e,n,o){for(var r,s=i(t,null,o,[]),a=t.length;a--;)(r=s[a])&&(t[a]=!(e[a]=r))})):function(t,o,r){return e[0]=t,i(e,null,r,n),e[0]=null,!n.pop()}})),has:et((function(t){return function(e){return J(t,e).length>0}})),contains:et((function(t){return t=t.replace(U,V),function(e){return(e.textContent||x.text(e)).indexOf(t)>-1}})),lang:et((function(t){return B.test(t||"")||J.error("unsupported lang: "+t),t=t.replace(U,V).toLowerCase(),function(e){var n;do{if(n=f?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(n=n.toLowerCase())===t||0===n.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}})),target:function(t){var e=i.location&&i.location.hash;return e&&e.slice(1)===t.id},root:function(t){return t===u},focus:function(t){return t===function(){try{return l.activeElement}catch(t){}}()&&l.hasFocus()&&!!(t.type||t.href||~t.tabIndex)},enabled:rt(!1),disabled:rt(!0),checked:function(t){return O(t,"input")&&!!t.checked||O(t,"option")&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!e.pseudos.empty(t)},header:function(t){return G.test(t.nodeName)},input:function(t){return Q.test(t.nodeName)},button:function(t){return O(t,"input")&&"button"===t.type||O(t,"button")},text:function(t){var e;return O(t,"input")&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:st((function(){return[0]})),last:st((function(t,e){return[e-1]})),eq:st((function(t,e,n){return[n<0?n+e:n]})),even:st((function(t,e){for(var n=0;ne?e:n;--i>=0;)t.push(i);return t})),gt:st((function(t,e,n){for(var i=n<0?n+e:n;++i1?function(e,n,i){for(var o=t.length;o--;)if(!t[o](e,n,i))return!1;return!0}:t[0]}function pt(t,e,n,i,o){for(var r,s=[],a=0,l=t.length,u=null!=e;a-1&&(r[u]=!(s[u]=d))}}else h=pt(h===s?h.splice(g,h.length):h),o?o(null,s,h,l):v.apply(s,h)}))}function mt(t){for(var i,o,r,s=t.length,a=e.relative[t[0].type],l=a||e.relative[" "],u=a?1:0,f=dt((function(t){return t===i}),l,!0),d=dt((function(t){return c.call(i,t)>-1}),l,!0),h=[function(t,e,o){var r=!a&&(o||e!=n)||((i=e).nodeType?f(t,e,o):d(t,e,o));return i=null,r}];u1&&ht(h),u>1&&ft(t.slice(0,u-1).concat({value:" "===t[u-2].type?"*":""})).replace(P,"$1"),o,u0,r=t.length>0,s=function(s,a,u,c,d){var h,p,m,g=0,b="0",w=s&&[],k=[],j=n,_=s||r&&e.find.TAG("*",d),$=y+=null==j?1:Math.random()||.1,C=_.length;for(d&&(n=a==l||a||d);b!==C&&null!=(h=_[b]);b++){if(r&&h){for(p=0,a||h.ownerDocument==l||(lt(h),u=!f);m=t[p++];)if(m(h,a||l,u)){v.call(c,h);break}d&&(y=$)}o&&((h=!m&&h)&&g--,s&&w.push(h))}if(g+=b,o&&b!==g){for(p=0;m=i[p++];)m(w,k,a,u);if(s){if(g>0)for(;b--;)w[b]||k[b]||(k[b]=T.call(c));k=pt(k)}v.apply(c,k),d&&!s&&k.length>0&&g+i.length>1&&x.uniqueSort(c)}return d&&(y=$,n=j),w};return o?et(s):s}(s,r)),a.selector=t}return a}function yt(t,n,i,o){var r,s,a,l,u,c="function"==typeof t&&t,d=!o&&ct(t=c.selector||t);if(i=i||[],1===d.length){if((s=d[0]=d[0].slice(0)).length>2&&"ID"===(a=s[0]).type&&9===n.nodeType&&f&&e.relative[s[1].type]){if(!(n=(e.find.ID(a.matches[0].replace(U,V),n)||[])[0]))return i;c&&(n=n.parentNode),t=t.slice(s.shift().value.length)}for(r=W.needsContext.test(t)?0:s.length;r--&&(a=s[r],!e.relative[l=a.type]);)if((u=e.find[l])&&(o=u(a.matches[0].replace(U,V),K.test(s[0].type)&&at(n.parentNode)||n))){if(s.splice(r,1),!(t=o.length&&ft(s)))return v.apply(i,o),i;break}}return(c||gt(t,d))(o,n,!f,i,!n||K.test(t)&&at(n.parentNode)||n),i}ut.prototype=e.filters=e.pseudos,e.setFilters=new ut,m.sortStable=g.split("").sort($).join("")===g,lt(),m.sortDetached=nt((function(t){return 1&t.compareDocumentPosition(l.createElement("fieldset"))})),x.find=J,x.expr[":"]=x.expr.pseudos,x.unique=x.uniqueSort,J.compile=gt,J.select=yt,J.setDocument=lt,J.tokenize=ct,J.escape=x.escapeSelector,J.getText=x.text,J.isXML=x.isXMLDoc,J.selectors=x.expr,J.support=x.support,J.uniqueSort=x.uniqueSort}();var M=function(t,e,n){for(var i=[],o=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(o&&x(t).is(n))break;i.push(t)}return i},H=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},q=x.expr.match.needsContext,I=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function F(t,e,n){return g(e)?x.grep(t,(function(t,i){return!!e.call(t,i,t)!==n})):e.nodeType?x.grep(t,(function(t){return t===e!==n})):"string"!=typeof e?x.grep(t,(function(t){return c.call(e,t)>-1!==n})):x.filter(e,t,n)}x.filter=function(t,e,n){var i=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===i.nodeType?x.find.matchesSelector(i,t)?[i]:[]:x.find.matches(t,x.grep(e,(function(t){return 1===t.nodeType})))},x.fn.extend({find:function(t){var e,n,i=this.length,o=this;if("string"!=typeof t)return this.pushStack(x(t).filter((function(){for(e=0;e1?x.uniqueSort(n):n},filter:function(t){return this.pushStack(F(this,t||[],!1))},not:function(t){return this.pushStack(F(this,t||[],!0))},is:function(t){return!!F(this,"string"==typeof t&&q.test(t)?x(t):t||[],!1).length}});var N,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(x.fn.init=function(t,e,n){var i,o;if(!t)return this;if(n=n||N,"string"==typeof t){if(!(i="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:B.exec(t))||!i[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(i[1]){if(e=e instanceof x?e[0]:e,x.merge(this,x.parseHTML(i[1],e&&e.nodeType?e.ownerDocument||e:b,!0)),I.test(i[1])&&x.isPlainObject(e))for(i in e)g(this[i])?this[i](e[i]):this.attr(i,e[i]);return this}return(o=b.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):g(t)?void 0!==n.ready?n.ready(t):t(x):x.makeArray(t,this)}).prototype=x.fn,N=x(b);var W=/^(?:parents|prev(?:Until|All))/,Q={children:!0,contents:!0,next:!0,prev:!0};function G(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}x.fn.extend({has:function(t){var e=x(t,this),n=e.length;return this.filter((function(){for(var t=0;t-1:1===n.nodeType&&x.find.matchesSelector(n,t))){r.push(n);break}return this.pushStack(r.length>1?x.uniqueSort(r):r)},index:function(t){return t?"string"==typeof t?c.call(x(t),this[0]):c.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(x.uniqueSort(x.merge(this.get(),x(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),x.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return M(t,"parentNode")},parentsUntil:function(t,e,n){return M(t,"parentNode",n)},next:function(t){return G(t,"nextSibling")},prev:function(t){return G(t,"previousSibling")},nextAll:function(t){return M(t,"nextSibling")},prevAll:function(t){return M(t,"previousSibling")},nextUntil:function(t,e,n){return M(t,"nextSibling",n)},prevUntil:function(t,e,n){return M(t,"previousSibling",n)},siblings:function(t){return H((t.parentNode||{}).firstChild,t)},children:function(t){return H(t.firstChild)},contents:function(t){return null!=t.contentDocument&&s(t.contentDocument)?t.contentDocument:(O(t,"template")&&(t=t.content||t),x.merge([],t.childNodes))}},(function(t,e){x.fn[t]=function(n,i){var o=x.map(this,e,n);return"Until"!==t.slice(-5)&&(i=n),i&&"string"==typeof i&&(o=x.filter(i,o)),this.length>1&&(Q[t]||x.uniqueSort(o),W.test(t)&&o.reverse()),this.pushStack(o)}}));var Y=/[^\x20\t\r\n\f]+/g;function K(t){return t}function U(t){throw t}function V(t,e,n,i){var o;try{t&&g(o=t.promise)?o.call(t).done(e).fail(n):t&&g(o=t.then)?o.call(t,e,n):e.apply(void 0,[t].slice(i))}catch(t){n.apply(void 0,[t])}}x.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return x.each(t.match(Y)||[],(function(t,n){e[n]=!0})),e}(t):x.extend({},t);var e,n,i,o,r=[],s=[],a=-1,l=function(){for(o=o||t.once,i=e=!0;s.length;a=-1)for(n=s.shift();++a-1;)r.splice(n,1),n<=a&&a--})),this},has:function(t){return t?x.inArray(t,r)>-1:r.length>0},empty:function(){return r&&(r=[]),this},disable:function(){return o=s=[],r=n="",this},disabled:function(){return!r},lock:function(){return o=s=[],n||e||(r=n=""),this},locked:function(){return!!o},fireWith:function(t,n){return o||(n=[t,(n=n||[]).slice?n.slice():n],s.push(n),e||l()),this},fire:function(){return u.fireWith(this,arguments),this},fired:function(){return!!i}};return u},x.extend({Deferred:function(t){var e=[["notify","progress",x.Callbacks("memory"),x.Callbacks("memory"),2],["resolve","done",x.Callbacks("once memory"),x.Callbacks("once memory"),0,"resolved"],["reject","fail",x.Callbacks("once memory"),x.Callbacks("once memory"),1,"rejected"]],n="pending",o={state:function(){return n},always:function(){return r.done(arguments).fail(arguments),this},catch:function(t){return o.then(null,t)},pipe:function(){var t=arguments;return x.Deferred((function(n){x.each(e,(function(e,i){var o=g(t[i[4]])&&t[i[4]];r[i[1]]((function(){var t=o&&o.apply(this,arguments);t&&g(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[i[0]+"With"](this,o?[t]:arguments)}))})),t=null})).promise()},then:function(t,n,o){var r=0;function s(t,e,n,o){return function(){var a=this,l=arguments,u=function(){var i,u;if(!(t=r&&(n!==U&&(a=void 0,l=[i]),e.rejectWith(a,l))}};t?c():(x.Deferred.getErrorHook?c.error=x.Deferred.getErrorHook():x.Deferred.getStackHook&&(c.error=x.Deferred.getStackHook()),i.setTimeout(c))}}return x.Deferred((function(i){e[0][3].add(s(0,i,g(o)?o:K,i.notifyWith)),e[1][3].add(s(0,i,g(t)?t:K)),e[2][3].add(s(0,i,g(n)?n:U))})).promise()},promise:function(t){return null!=t?x.extend(t,o):o}},r={};return x.each(e,(function(t,i){var s=i[2],a=i[5];o[i[1]]=s.add,a&&s.add((function(){n=a}),e[3-t][2].disable,e[3-t][3].disable,e[0][2].lock,e[0][3].lock),s.add(i[3].fire),r[i[0]]=function(){return r[i[0]+"With"](this===r?void 0:this,arguments),this},r[i[0]+"With"]=s.fireWith})),o.promise(r),t&&t.call(r,r),r},when:function(t){var e=arguments.length,n=e,i=Array(n),o=a.call(arguments),r=x.Deferred(),s=function(t){return function(n){i[t]=this,o[t]=arguments.length>1?a.call(arguments):n,--e||r.resolveWith(i,o)}};if(e<=1&&(V(t,r.done(s(n)).resolve,r.reject,!e),"pending"===r.state()||g(o[n]&&o[n].then)))return r.then();for(;n--;)V(o[n],s(n),r.reject);return r.promise()}});var X=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;x.Deferred.exceptionHook=function(t,e){i.console&&i.console.warn&&t&&X.test(t.name)&&i.console.warn("jQuery.Deferred exception: "+t.message,t.stack,e)},x.readyException=function(t){i.setTimeout((function(){throw t}))};var Z=x.Deferred();function J(){b.removeEventListener("DOMContentLoaded",J),i.removeEventListener("load",J),x.ready()}x.fn.ready=function(t){return Z.then(t).catch((function(t){x.readyException(t)})),this},x.extend({isReady:!1,readyWait:1,ready:function(t){(!0===t?--x.readyWait:x.isReady)||(x.isReady=!0,!0!==t&&--x.readyWait>0||Z.resolveWith(b,[x]))}}),x.ready.then=Z.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?i.setTimeout(x.ready):(b.addEventListener("DOMContentLoaded",J),i.addEventListener("load",J));var tt=function(t,e,n,i,o,r,s){var a=0,l=t.length,u=null==n;if("object"===j(n))for(a in o=!0,n)tt(t,e,a,n[a],!0,r,s);else if(void 0!==i&&(o=!0,g(i)||(s=!0),u&&(s?(e.call(t,i),e=null):(u=e,e=function(t,e,n){return u.call(x(t),n)})),e))for(;a1,null,!0)},removeData:function(t){return this.each((function(){lt.remove(this,t)}))}}),x.extend({queue:function(t,e,n){var i;if(t)return e=(e||"fx")+"queue",i=at.get(t,e),n&&(!i||Array.isArray(n)?i=at.access(t,e,x.makeArray(n)):i.push(n)),i||[]},dequeue:function(t,e){e=e||"fx";var n=x.queue(t,e),i=n.length,o=n.shift(),r=x._queueHooks(t,e);"inprogress"===o&&(o=n.shift(),i--),o&&("fx"===e&&n.unshift("inprogress"),delete r.stop,o.call(t,(function(){x.dequeue(t,e)}),r)),!i&&r&&r.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return at.get(t,n)||at.access(t,n,{empty:x.Callbacks("once memory").add((function(){at.remove(t,[e+"queue",n])}))})}}),x.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length\x20\t\r\n\f]*)/i,Ot=/^$|^module$|\/(?:java|ecma)script/i;_t=b.createDocumentFragment().appendChild(b.createElement("div")),($t=b.createElement("input")).setAttribute("type","radio"),$t.setAttribute("checked","checked"),$t.setAttribute("name","t"),_t.appendChild($t),m.checkClone=_t.cloneNode(!0).cloneNode(!0).lastChild.checked,_t.innerHTML="",m.noCloneChecked=!!_t.cloneNode(!0).lastChild.defaultValue,_t.innerHTML="",m.option=!!_t.lastChild;var Tt={thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function St(t,e){var n;return n=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&O(t,e)?x.merge([t],n):n}function Et(t,e){for(var n=0,i=t.length;n",""]);var zt=/<|&#?\w+;/;function Pt(t,e,n,i,o){for(var r,s,a,l,u,c,f=e.createDocumentFragment(),d=[],h=0,p=t.length;h-1)o&&o.push(r);else if(u=mt(r),s=St(f.appendChild(r),"script"),u&&Et(s),n)for(c=0;r=s[c++];)Ot.test(r.type||"")&&n.push(r);return f}var At=/^([^.]*)(?:\.(.+)|)/;function Rt(){return!0}function Dt(){return!1}function Lt(t,e,n,i,o,r){var s,a;if("object"==typeof e){for(a in"string"!=typeof n&&(i=i||n,n=void 0),e)Lt(t,a,n,i,e[a],r);return t}if(null==i&&null==o?(o=n,i=n=void 0):null==o&&("string"==typeof n?(o=i,i=void 0):(o=i,i=n,n=void 0)),!1===o)o=Dt;else if(!o)return t;return 1===r&&(s=o,o=function(t){return x().off(t),s.apply(this,arguments)},o.guid=s.guid||(s.guid=x.guid++)),t.each((function(){x.event.add(this,e,o,i,n)}))}function Mt(t,e,n){n?(at.set(t,e,!1),x.event.add(t,e,{namespace:!1,handler:function(t){var n,i=at.get(this,e);if(1&t.isTrigger&&this[e]){if(i)(x.event.special[e]||{}).delegateType&&t.stopPropagation();else if(i=a.call(arguments),at.set(this,e,i),this[e](),n=at.get(this,e),at.set(this,e,!1),i!==n)return t.stopImmediatePropagation(),t.preventDefault(),n}else i&&(at.set(this,e,x.event.trigger(i[0],i.slice(1),this)),t.stopPropagation(),t.isImmediatePropagationStopped=Rt)}})):void 0===at.get(t,e)&&x.event.add(t,e,Rt)}x.event={global:{},add:function(t,e,n,i,o){var r,s,a,l,u,c,f,d,h,p,v,m=at.get(t);if(rt(t))for(n.handler&&(n=(r=n).handler,o=r.selector),o&&x.find.matchesSelector(vt,o),n.guid||(n.guid=x.guid++),(l=m.events)||(l=m.events=Object.create(null)),(s=m.handle)||(s=m.handle=function(e){return void 0!==x&&x.event.triggered!==e.type?x.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(Y)||[""]).length;u--;)h=v=(a=At.exec(e[u])||[])[1],p=(a[2]||"").split(".").sort(),h&&(f=x.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=x.event.special[h]||{},c=x.extend({type:h,origType:v,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:p.join(".")},r),(d=l[h])||((d=l[h]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,i,p,s)||t.addEventListener&&t.addEventListener(h,s)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),o?d.splice(d.delegateCount++,0,c):d.push(c),x.event.global[h]=!0)},remove:function(t,e,n,i,o){var r,s,a,l,u,c,f,d,h,p,v,m=at.hasData(t)&&at.get(t);if(m&&(l=m.events)){for(u=(e=(e||"").match(Y)||[""]).length;u--;)if(h=v=(a=At.exec(e[u])||[])[1],p=(a[2]||"").split(".").sort(),h){for(f=x.event.special[h]||{},d=l[h=(i?f.delegateType:f.bindType)||h]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=r=d.length;r--;)c=d[r],!o&&v!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(d.splice(r,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(t,c));s&&!d.length&&(f.teardown&&!1!==f.teardown.call(t,p,m.handle)||x.removeEvent(t,h,m.handle),delete l[h])}else for(h in l)x.event.remove(t,h+e[u],n,i,!0);x.isEmptyObject(l)&&at.remove(t,"handle events")}},dispatch:function(t){var e,n,i,o,r,s,a=new Array(arguments.length),l=x.event.fix(t),u=(at.get(this,"events")||Object.create(null))[l.type]||[],c=x.event.special[l.type]||{};for(a[0]=l,e=1;e=1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&("click"!==t.type||!0!==u.disabled)){for(r=[],s={},n=0;n-1:x.find(o,this,null,[u]).length),s[o]&&r.push(i);r.length&&a.push({elem:u,handlers:r})}return u=this,l\s*$/g;function Ft(t,e){return O(t,"table")&&O(11!==e.nodeType?e:e.firstChild,"tr")&&x(t).children("tbody")[0]||t}function Nt(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function Bt(t){return"true/"===(t.type||"").slice(0,5)?t.type=t.type.slice(5):t.removeAttribute("type"),t}function Wt(t,e){var n,i,o,r,s,a;if(1===e.nodeType){if(at.hasData(t)&&(a=at.get(t).events))for(o in at.remove(e,"handle events"),a)for(n=0,i=a[o].length;n1&&"string"==typeof p&&!m.checkClone&&qt.test(p))return t.each((function(o){var r=t.eq(o);v&&(e[0]=p.call(this,o,r.html())),Gt(r,e,n,i)}));if(d&&(r=(o=Pt(e,t[0].ownerDocument,!1,t,i)).firstChild,1===o.childNodes.length&&(o=r),r||i)){for(a=(s=x.map(St(o,"script"),Nt)).length;f0&&Et(s,!l&&St(t,"script")),a},cleanData:function(t){for(var e,n,i,o=x.event.special,r=0;void 0!==(n=t[r]);r++)if(rt(n)){if(e=n[at.expando]){if(e.events)for(i in e.events)o[i]?x.event.remove(n,i):x.removeEvent(n,i,e.handle);n[at.expando]=void 0}n[lt.expando]&&(n[lt.expando]=void 0)}}}),x.fn.extend({detach:function(t){return Yt(this,t,!0)},remove:function(t){return Yt(this,t)},text:function(t){return tt(this,(function(t){return void 0===t?x.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)}))}),null,t,arguments.length)},append:function(){return Gt(this,arguments,(function(t){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Ft(this,t).appendChild(t)}))},prepend:function(){return Gt(this,arguments,(function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=Ft(this,t);e.insertBefore(t,e.firstChild)}}))},before:function(){return Gt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this)}))},after:function(){return Gt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)}))},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(x.cleanData(St(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map((function(){return x.clone(this,t,e)}))},html:function(t){return tt(this,(function(t){var e=this[0]||{},n=0,i=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!Ht.test(t)&&!Tt[(Ct.exec(t)||["",""])[1].toLowerCase()]){t=x.htmlPrefilter(t);try{for(;n=0&&(l+=Math.max(0,Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-r-l-a-.5))||0),l+u}function ce(t,e,n){var i=Vt(t),o=(!m.boxSizingReliable()||n)&&"border-box"===x.css(t,"boxSizing",!1,i),r=o,s=Jt(t,e,i),a="offset"+e[0].toUpperCase()+e.slice(1);if(Kt.test(s)){if(!n)return s;s="auto"}return(!m.boxSizingReliable()&&o||!m.reliableTrDimensions()&&O(t,"tr")||"auto"===s||!parseFloat(s)&&"inline"===x.css(t,"display",!1,i))&&t.getClientRects().length&&(o="border-box"===x.css(t,"boxSizing",!1,i),(r=a in t)&&(s=t[a])),(s=parseFloat(s)||0)+ue(t,e,n||(o?"border":"content"),r,i,s)+"px"}function fe(t,e,n,i,o){return new fe.prototype.init(t,e,n,i,o)}x.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=Jt(t,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(t,e,n,i){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var o,r,s,a=ot(e),l=Ut.test(e),u=t.style;if(l||(e=oe(a)),s=x.cssHooks[e]||x.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(o=s.get(t,!1,i))?o:u[e];"string"==(r=typeof n)&&(o=ht.exec(n))&&o[1]&&(n=bt(t,e,o),r="number"),null!=n&&n==n&&("number"!==r||l||(n+=o&&o[3]||(x.cssNumber[a]?"":"px")),m.clearCloneStyle||""!==n||0!==e.indexOf("background")||(u[e]="inherit"),s&&"set"in s&&void 0===(n=s.set(t,n,i))||(l?u.setProperty(e,n):u[e]=n))}},css:function(t,e,n,i){var o,r,s,a=ot(e);return Ut.test(e)||(e=oe(a)),(s=x.cssHooks[e]||x.cssHooks[a])&&"get"in s&&(o=s.get(t,!0,n)),void 0===o&&(o=Jt(t,e,i)),"normal"===o&&e in ae&&(o=ae[e]),""===n||n?(r=parseFloat(o),!0===n||isFinite(r)?r||0:o):o}}),x.each(["height","width"],(function(t,e){x.cssHooks[e]={get:function(t,n,i){if(n)return!re.test(x.css(t,"display"))||t.getClientRects().length&&t.getBoundingClientRect().width?ce(t,e,i):Xt(t,se,(function(){return ce(t,e,i)}))},set:function(t,n,i){var o,r=Vt(t),s=!m.scrollboxSize()&&"absolute"===r.position,a=(s||i)&&"border-box"===x.css(t,"boxSizing",!1,r),l=i?ue(t,e,i,a,r):0;return a&&s&&(l-=Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-parseFloat(r[e])-ue(t,e,"border",!1,r)-.5)),l&&(o=ht.exec(n))&&"px"!==(o[3]||"px")&&(t.style[e]=n,n=x.css(t,e)),le(0,n,l)}}})),x.cssHooks.marginLeft=te(m.reliableMarginLeft,(function(t,e){if(e)return(parseFloat(Jt(t,"marginLeft"))||t.getBoundingClientRect().left-Xt(t,{marginLeft:0},(function(){return t.getBoundingClientRect().left})))+"px"})),x.each({margin:"",padding:"",border:"Width"},(function(t,e){x.cssHooks[t+e]={expand:function(n){for(var i=0,o={},r="string"==typeof n?n.split(" "):[n];i<4;i++)o[t+pt[i]+e]=r[i]||r[i-2]||r[0];return o}},"margin"!==t&&(x.cssHooks[t+e].set=le)})),x.fn.extend({css:function(t,e){return tt(this,(function(t,e,n){var i,o,r={},s=0;if(Array.isArray(e)){for(i=Vt(t),o=e.length;s1)}}),x.Tween=fe,fe.prototype={constructor:fe,init:function(t,e,n,i,o,r){this.elem=t,this.prop=n,this.easing=o||x.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=i,this.unit=r||(x.cssNumber[n]?"":"px")},cur:function(){var t=fe.propHooks[this.prop];return t&&t.get?t.get(this):fe.propHooks._default.get(this)},run:function(t){var e,n=fe.propHooks[this.prop];return this.options.duration?this.pos=e=x.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):fe.propHooks._default.set(this),this}},fe.prototype.init.prototype=fe.prototype,fe.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=x.css(t.elem,t.prop,""))&&"auto"!==e?e:0},set:function(t){x.fx.step[t.prop]?x.fx.step[t.prop](t):1!==t.elem.nodeType||!x.cssHooks[t.prop]&&null==t.elem.style[oe(t.prop)]?t.elem[t.prop]=t.now:x.style(t.elem,t.prop,t.now+t.unit)}}},fe.propHooks.scrollTop=fe.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},x.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},x.fx=fe.prototype.init,x.fx.step={};var de,he,pe=/^(?:toggle|show|hide)$/,ve=/queueHooks$/;function me(){he&&(!1===b.hidden&&i.requestAnimationFrame?i.requestAnimationFrame(me):i.setTimeout(me,x.fx.interval),x.fx.tick())}function ge(){return i.setTimeout((function(){de=void 0})),de=Date.now()}function ye(t,e){var n,i=0,o={height:t};for(e=e?1:0;i<4;i+=2-e)o["margin"+(n=pt[i])]=o["padding"+n]=t;return e&&(o.opacity=o.width=t),o}function be(t,e,n){for(var i,o=(we.tweeners[e]||[]).concat(we.tweeners["*"]),r=0,s=o.length;r1)},removeAttr:function(t){return this.each((function(){x.removeAttr(this,t)}))}}),x.extend({attr:function(t,e,n){var i,o,r=t.nodeType;if(3!==r&&8!==r&&2!==r)return void 0===t.getAttribute?x.prop(t,e,n):(1===r&&x.isXMLDoc(t)||(o=x.attrHooks[e.toLowerCase()]||(x.expr.match.bool.test(e)?ke:void 0)),void 0!==n?null===n?void x.removeAttr(t,e):o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:(t.setAttribute(e,n+""),n):o&&"get"in o&&null!==(i=o.get(t,e))?i:null==(i=x.find.attr(t,e))?void 0:i)},attrHooks:{type:{set:function(t,e){if(!m.radioValue&&"radio"===e&&O(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}},removeAttr:function(t,e){var n,i=0,o=e&&e.match(Y);if(o&&1===t.nodeType)for(;n=o[i++];)t.removeAttribute(n)}}),ke={set:function(t,e,n){return!1===e?x.removeAttr(t,n):t.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\w+/g),(function(t,e){var n=je[e]||x.find.attr;je[e]=function(t,e,i){var o,r,s=e.toLowerCase();return i||(r=je[s],je[s]=o,o=null!=n(t,e,i)?s:null,je[s]=r),o}}));var _e=/^(?:input|select|textarea|button)$/i,$e=/^(?:a|area)$/i;function xe(t){return(t.match(Y)||[]).join(" ")}function Ce(t){return t.getAttribute&&t.getAttribute("class")||""}function Oe(t){return Array.isArray(t)?t:"string"==typeof t&&t.match(Y)||[]}x.fn.extend({prop:function(t,e){return tt(this,x.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each((function(){delete this[x.propFix[t]||t]}))}}),x.extend({prop:function(t,e,n){var i,o,r=t.nodeType;if(3!==r&&8!==r&&2!==r)return 1===r&&x.isXMLDoc(t)||(e=x.propFix[e]||e,o=x.propHooks[e]),void 0!==n?o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:t[e]=n:o&&"get"in o&&null!==(i=o.get(t,e))?i:t[e]},propHooks:{tabIndex:{get:function(t){var e=x.find.attr(t,"tabindex");return e?parseInt(e,10):_e.test(t.nodeName)||$e.test(t.nodeName)&&t.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),m.optSelected||(x.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(t){var e=t.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){x.propFix[this.toLowerCase()]=this})),x.fn.extend({addClass:function(t){var e,n,i,o,r,s;return g(t)?this.each((function(e){x(this).addClass(t.call(this,e,Ce(this)))})):(e=Oe(t)).length?this.each((function(){if(i=Ce(this),n=1===this.nodeType&&" "+xe(i)+" "){for(r=0;r-1;)n=n.replace(" "+o+" "," ");s=xe(n),i!==s&&this.setAttribute("class",s)}})):this:this.attr("class","")},toggleClass:function(t,e){var n,i,o,r,s=typeof t,a="string"===s||Array.isArray(t);return g(t)?this.each((function(n){x(this).toggleClass(t.call(this,n,Ce(this),e),e)})):"boolean"==typeof e&&a?e?this.addClass(t):this.removeClass(t):(n=Oe(t),this.each((function(){if(a)for(r=x(this),o=0;o-1)return!0;return!1}});var Te=/\r/g;x.fn.extend({val:function(t){var e,n,i,o=this[0];return arguments.length?(i=g(t),this.each((function(n){var o;1===this.nodeType&&(null==(o=i?t.call(this,n,x(this).val()):t)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=x.map(o,(function(t){return null==t?"":t+""}))),(e=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()])&&"set"in e&&void 0!==e.set(this,o,"value")||(this.value=o))}))):o?(e=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()])&&"get"in e&&void 0!==(n=e.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(Te,""):null==n?"":n:void 0}}),x.extend({valHooks:{option:{get:function(t){var e=x.find.attr(t,"value");return null!=e?e:xe(x.text(t))}},select:{get:function(t){var e,n,i,o=t.options,r=t.selectedIndex,s="select-one"===t.type,a=s?null:[],l=s?r+1:o.length;for(i=r<0?l:s?r:0;i-1)&&(n=!0);return n||(t.selectedIndex=-1),r}}}}),x.each(["radio","checkbox"],(function(){x.valHooks[this]={set:function(t,e){if(Array.isArray(e))return t.checked=x.inArray(x(t).val(),e)>-1}},m.checkOn||(x.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})}));var Se=i.location,Ee={guid:Date.now()},ze=/\?/;x.parseXML=function(t){var e,n;if(!t||"string"!=typeof t)return null;try{e=(new i.DOMParser).parseFromString(t,"text/xml")}catch(t){}return n=e&&e.getElementsByTagName("parsererror")[0],e&&!n||x.error("Invalid XML: "+(n?x.map(n.childNodes,(function(t){return t.textContent})).join("\n"):t)),e};var Pe=/^(?:focusinfocus|focusoutblur)$/,Ae=function(t){t.stopPropagation()};x.extend(x.event,{trigger:function(t,e,n,o){var r,s,a,l,u,c,f,d,p=[n||b],v=h.call(t,"type")?t.type:t,m=h.call(t,"namespace")?t.namespace.split("."):[];if(s=d=a=n=n||b,3!==n.nodeType&&8!==n.nodeType&&!Pe.test(v+x.event.triggered)&&(v.indexOf(".")>-1&&(m=v.split("."),v=m.shift(),m.sort()),u=v.indexOf(":")<0&&"on"+v,(t=t[x.expando]?t:new x.Event(v,"object"==typeof t&&t)).isTrigger=o?2:3,t.namespace=m.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=n),e=null==e?[t]:x.makeArray(e,[t]),f=x.event.special[v]||{},o||!f.trigger||!1!==f.trigger.apply(n,e))){if(!o&&!f.noBubble&&!y(n)){for(l=f.delegateType||v,Pe.test(l+v)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(n.ownerDocument||b)&&p.push(a.defaultView||a.parentWindow||i)}for(r=0;(s=p[r++])&&!t.isPropagationStopped();)d=s,t.type=r>1?l:f.bindType||v,(c=(at.get(s,"events")||Object.create(null))[t.type]&&at.get(s,"handle"))&&c.apply(s,e),(c=u&&s[u])&&c.apply&&rt(s)&&(t.result=c.apply(s,e),!1===t.result&&t.preventDefault());return t.type=v,o||t.isDefaultPrevented()||f._default&&!1!==f._default.apply(p.pop(),e)||!rt(n)||u&&g(n[v])&&!y(n)&&((a=n[u])&&(n[u]=null),x.event.triggered=v,t.isPropagationStopped()&&d.addEventListener(v,Ae),n[v](),t.isPropagationStopped()&&d.removeEventListener(v,Ae),x.event.triggered=void 0,a&&(n[u]=a)),t.result}},simulate:function(t,e,n){var i=x.extend(new x.Event,n,{type:t,isSimulated:!0});x.event.trigger(i,null,e)}}),x.fn.extend({trigger:function(t,e){return this.each((function(){x.event.trigger(t,e,this)}))},triggerHandler:function(t,e){var n=this[0];if(n)return x.event.trigger(t,e,n,!0)}});var Re=/\[\]$/,De=/\r?\n/g,Le=/^(?:submit|button|image|reset|file)$/i,Me=/^(?:input|select|textarea|keygen)/i;function He(t,e,n,i){var o;if(Array.isArray(e))x.each(e,(function(e,o){n||Re.test(t)?i(t,o):He(t+"["+("object"==typeof o&&null!=o?e:"")+"]",o,n,i)}));else if(n||"object"!==j(e))i(t,e);else for(o in e)He(t+"["+o+"]",e[o],n,i)}x.param=function(t,e){var n,i=[],o=function(t,e){var n=g(e)?e():e;i[i.length]=encodeURIComponent(t)+"="+encodeURIComponent(null==n?"":n)};if(null==t)return"";if(Array.isArray(t)||t.jquery&&!x.isPlainObject(t))x.each(t,(function(){o(this.name,this.value)}));else for(n in t)He(n,t[n],e,o);return i.join("&")},x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var t=x.prop(this,"elements");return t?x.makeArray(t):this})).filter((function(){var t=this.type;return this.name&&!x(this).is(":disabled")&&Me.test(this.nodeName)&&!Le.test(t)&&(this.checked||!xt.test(t))})).map((function(t,e){var n=x(this).val();return null==n?null:Array.isArray(n)?x.map(n,(function(t){return{name:e.name,value:t.replace(De,"\r\n")}})):{name:e.name,value:n.replace(De,"\r\n")}})).get()}});var qe=/%20/g,Ie=/#.*$/,Fe=/([?&])_=[^&]*/,Ne=/^(.*?):[ \t]*([^\r\n]*)$/gm,Be=/^(?:GET|HEAD)$/,We=/^\/\//,Qe={},Ge={},Ye="*/".concat("*"),Ke=b.createElement("a");function Ue(t){return function(e,n){"string"!=typeof e&&(n=e,e="*");var i,o=0,r=e.toLowerCase().match(Y)||[];if(g(n))for(;i=r[o++];)"+"===i[0]?(i=i.slice(1)||"*",(t[i]=t[i]||[]).unshift(n)):(t[i]=t[i]||[]).push(n)}}function Ve(t,e,n,i){var o={},r=t===Ge;function s(a){var l;return o[a]=!0,x.each(t[a]||[],(function(t,a){var u=a(e,n,i);return"string"!=typeof u||r||o[u]?r?!(l=u):void 0:(e.dataTypes.unshift(u),s(u),!1)})),l}return s(e.dataTypes[0])||!o["*"]&&s("*")}function Xe(t,e){var n,i,o=x.ajaxSettings.flatOptions||{};for(n in e)void 0!==e[n]&&((o[n]?t:i||(i={}))[n]=e[n]);return i&&x.extend(!0,t,i),t}Ke.href=Se.href,x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Se.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Se.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Ye,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?Xe(Xe(t,x.ajaxSettings),e):Xe(x.ajaxSettings,t)},ajaxPrefilter:Ue(Qe),ajaxTransport:Ue(Ge),ajax:function(t,e){"object"==typeof t&&(e=t,t=void 0),e=e||{};var n,o,r,s,a,l,u,c,f,d,h=x.ajaxSetup({},e),p=h.context||h,v=h.context&&(p.nodeType||p.jquery)?x(p):x.event,m=x.Deferred(),g=x.Callbacks("once memory"),y=h.statusCode||{},w={},k={},j="canceled",_={readyState:0,getResponseHeader:function(t){var e;if(u){if(!s)for(s={};e=Ne.exec(r);)s[e[1].toLowerCase()+" "]=(s[e[1].toLowerCase()+" "]||[]).concat(e[2]);e=s[t.toLowerCase()+" "]}return null==e?null:e.join(", ")},getAllResponseHeaders:function(){return u?r:null},setRequestHeader:function(t,e){return null==u&&(t=k[t.toLowerCase()]=k[t.toLowerCase()]||t,w[t]=e),this},overrideMimeType:function(t){return null==u&&(h.mimeType=t),this},statusCode:function(t){var e;if(t)if(u)_.always(t[_.status]);else for(e in t)y[e]=[y[e],t[e]];return this},abort:function(t){var e=t||j;return n&&n.abort(e),$(0,e),this}};if(m.promise(_),h.url=((t||h.url||Se.href)+"").replace(We,Se.protocol+"//"),h.type=e.method||e.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(Y)||[""],null==h.crossDomain){l=b.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Ke.protocol+"//"+Ke.host!=l.protocol+"//"+l.host}catch(t){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=x.param(h.data,h.traditional)),Ve(Qe,h,e,_),u)return _;for(f in(c=x.event&&h.global)&&0==x.active++&&x.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Be.test(h.type),o=h.url.replace(Ie,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qe,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(ze.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Fe,"$1"),d=(ze.test(o)?"&":"?")+"_="+Ee.guid+++d),h.url=o+d),h.ifModified&&(x.lastModified[o]&&_.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&_.setRequestHeader("If-None-Match",x.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||e.contentType)&&_.setRequestHeader("Content-Type",h.contentType),_.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Ye+"; q=0.01":""):h.accepts["*"]),h.headers)_.setRequestHeader(f,h.headers[f]);if(h.beforeSend&&(!1===h.beforeSend.call(p,_,h)||u))return _.abort();if(j="abort",g.add(h.complete),_.done(h.success),_.fail(h.error),n=Ve(Ge,h,e,_)){if(_.readyState=1,c&&v.trigger("ajaxSend",[_,h]),u)return _;h.async&&h.timeout>0&&(a=i.setTimeout((function(){_.abort("timeout")}),h.timeout));try{u=!1,n.send(w,$)}catch(t){if(u)throw t;$(-1,t)}}else $(-1,"No Transport");function $(t,e,s,l){var f,d,b,w,k,j=e;u||(u=!0,a&&i.clearTimeout(a),n=void 0,r=l||"",_.readyState=t>0?4:0,f=t>=200&&t<300||304===t,s&&(w=function(t,e,n){for(var i,o,r,s,a=t.contents,l=t.dataTypes;"*"===l[0];)l.shift(),void 0===i&&(i=t.mimeType||e.getResponseHeader("Content-Type"));if(i)for(o in a)if(a[o]&&a[o].test(i)){l.unshift(o);break}if(l[0]in n)r=l[0];else{for(o in n){if(!l[0]||t.converters[o+" "+l[0]]){r=o;break}s||(s=o)}r=r||s}if(r)return r!==l[0]&&l.unshift(r),n[r]}(h,_,s)),!f&&x.inArray("script",h.dataTypes)>-1&&x.inArray("json",h.dataTypes)<0&&(h.converters["text script"]=function(){}),w=function(t,e,n,i){var o,r,s,a,l,u={},c=t.dataTypes.slice();if(c[1])for(s in t.converters)u[s.toLowerCase()]=t.converters[s];for(r=c.shift();r;)if(t.responseFields[r]&&(n[t.responseFields[r]]=e),!l&&i&&t.dataFilter&&(e=t.dataFilter(e,t.dataType)),l=r,r=c.shift())if("*"===r)r=l;else if("*"!==l&&l!==r){if(!(s=u[l+" "+r]||u["* "+r]))for(o in u)if((a=o.split(" "))[1]===r&&(s=u[l+" "+a[0]]||u["* "+a[0]])){!0===s?s=u[o]:!0!==u[o]&&(r=a[0],c.unshift(a[1]));break}if(!0!==s)if(s&&t.throws)e=s(e);else try{e=s(e)}catch(t){return{state:"parsererror",error:s?t:"No conversion from "+l+" to "+r}}}return{state:"success",data:e}}(h,w,_,f),f?(h.ifModified&&((k=_.getResponseHeader("Last-Modified"))&&(x.lastModified[o]=k),(k=_.getResponseHeader("etag"))&&(x.etag[o]=k)),204===t||"HEAD"===h.type?j="nocontent":304===t?j="notmodified":(j=w.state,d=w.data,f=!(b=w.error))):(b=j,!t&&j||(j="error",t<0&&(t=0))),_.status=t,_.statusText=(e||j)+"",f?m.resolveWith(p,[d,j,_]):m.rejectWith(p,[_,j,b]),_.statusCode(y),y=void 0,c&&v.trigger(f?"ajaxSuccess":"ajaxError",[_,h,f?d:b]),g.fireWith(p,[_,j]),c&&(v.trigger("ajaxComplete",[_,h]),--x.active||x.event.trigger("ajaxStop")))}return _},getJSON:function(t,e,n){return x.get(t,e,n,"json")},getScript:function(t,e){return x.get(t,void 0,e,"script")}}),x.each(["get","post"],(function(t,e){x[e]=function(t,n,i,o){return g(n)&&(o=o||i,i=n,n=void 0),x.ajax(x.extend({url:t,type:e,dataType:o,data:n,success:i},x.isPlainObject(t)&&t))}})),x.ajaxPrefilter((function(t){var e;for(e in t.headers)"content-type"===e.toLowerCase()&&(t.contentType=t.headers[e]||"")})),x._evalUrl=function(t,e,n){return x.ajax({url:t,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(t){x.globalEval(t,e,n)}})},x.fn.extend({wrapAll:function(t){var e;return this[0]&&(g(t)&&(t=t.call(this[0])),e=x(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map((function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t})).append(this)),this},wrapInner:function(t){return g(t)?this.each((function(e){x(this).wrapInner(t.call(this,e))})):this.each((function(){var e=x(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)}))},wrap:function(t){var e=g(t);return this.each((function(n){x(this).wrapAll(e?t.call(this,n):t)}))},unwrap:function(t){return this.parent(t).not("body").each((function(){x(this).replaceWith(this.childNodes)})),this}}),x.expr.pseudos.hidden=function(t){return!x.expr.pseudos.visible(t)},x.expr.pseudos.visible=function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)},x.ajaxSettings.xhr=function(){try{return new i.XMLHttpRequest}catch(t){}};var Ze={0:200,1223:204},Je=x.ajaxSettings.xhr();m.cors=!!Je&&"withCredentials"in Je,m.ajax=Je=!!Je,x.ajaxTransport((function(t){var e,n;if(m.cors||Je&&!t.crossDomain)return{send:function(o,r){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];for(s in t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest"),o)a.setRequestHeader(s,o[s]);e=function(t){return function(){e&&(e=n=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===t?a.abort():"error"===t?"number"!=typeof a.status?r(0,"error"):r(a.status,a.statusText):r(Ze[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=e(),n=a.onerror=a.ontimeout=e("error"),void 0!==a.onabort?a.onabort=n:a.onreadystatechange=function(){4===a.readyState&&i.setTimeout((function(){e&&n()}))},e=e("abort");try{a.send(t.hasContent&&t.data||null)}catch(t){if(e)throw t}},abort:function(){e&&e()}}})),x.ajaxPrefilter((function(t){t.crossDomain&&(t.contents.script=!1)})),x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return x.globalEval(t),t}}}),x.ajaxPrefilter("script",(function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")})),x.ajaxTransport("script",(function(t){var e,n;if(t.crossDomain||t.scriptAttrs)return{send:function(i,o){e=x(" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Build an IoT App with Go

      +
      +

      Introduction

      +

      In this section, we will walk you through the CarePet commands and explain the code behind them.

      +

      As explained in Getting Started with CarePet, the project is structured as follows:

      +
        +
      • Migrate (/cmd/migrate) - Creates the CarePet keyspace and tables.

      • +
      • Collar (/cmd/sensor) - Simulates a pet’s collar by generating the pet’s health data and pushing the data into the storage.

      • +
      • Server (/cmd/server) - REST API service for tracking the pets’ health state.

      • +
      +
      +
      +

      Migrate

      +

      The /migrate command creates the keyspace and tables that will be used by the collar and server services.

      +

      Line 25 to 27 in the /cmd/migrate/migrate.go file call the createKeyspace , migrateKeyspace then the printKeyspaceMetadata functions.

      +
      func main() {
      +	
      +	/// ...
      +
      +	createKeyspace()
      +	migrateKeyspace()
      +	printKeyspaceMetadata()
      +}
      +
      +
      +

      The createKeyspace function creates a new session then executes the following CQL query stored in the db.go file:

      +
      CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' } AND durable_writes = TRUE;
      +
      +
      +
      func createKeyspace() {
      +        // Creates a new session
      +	ses, err := config.Session()
      +	if err != nil {
      +		log.Fatalln("session: ", err)
      +	}
      +	defer ses.Close()
      +
      +        // Executes the CREATE KEYSPACE query and checks for errors
      +	if err := ses.Query(db.KeySpaceCQL).Exec(); err != nil {
      +		log.Fatalln("ensure keyspace exists: ", err)
      +	}
      +}
      +
      +
      +

      The migrateKeyspace function opens a new session with the carepet keyspace and creates the following tables in the carepet keyspace using the CQL file located in /db/cql/care-pet-ddl.cql:

      +
        +
      • owner

      • +
      • pet

      • +
      • sensor

      • +
      • measurement

      • +
      • sensor_avg

      • +
      +
      func migrateKeyspace() {
      +        // Create a new session with the carepet keyspace 
      +	ses, err := config.Keyspace()
      +	if err != nil {
      +		log.Fatalln("session: ", err)
      +	}
      +	defer ses.Close()
      +
      +        // Execute the queries in the migration file om db/cql
      +	if err := migrate.Migrate(context.Background(), ses, "db/cql"); err != nil {
      +		log.Fatalln("migrate: ", err)
      +	}
      +}
      +
      +
      +

      As the name suggests, the printKeyspaceMetadata function will then print the metadata related to the carepet keyspace and confirm that the tables were properly created.

      +
      +
      +

      Sensor

      +

      The sensor service simulates the collar’s activity. The service uses the pet struct and its functions defined in sensor/pet.go to create a new pet along with an owner and sensorType then saves it to the database.

      +
      func main() {
      +
      +	/// ...
      +
      +	// Create a new session with carepet keyspace
      +	ses, err := config.Keyspace()
      +	if err != nil {
      +		log.Fatalln("session: ", err)
      +	}
      +	defer ses.Close()
      +
      +	// Generate new pet
      +	pet := NewPet()
      +
      +	// Save new pet to the database
      +	if err := pet.save(context.Background(), ses); err != nil {
      +		log.Fatalln("pet save: ", err)
      +	}
      +
      +	log.Println("New owner #", pet.p.OwnerID)
      +	log.Println("New pet #", pet.p.PetID)
      +
      +	pet.run(context.Background(), ses)
      +}
      +
      +
      +
      +
      +

      Server

      +

      The server service is a REST API for tracking the pets’ health state. The service allows users to query the database via http.

      +

      In the care-pet example, you will use $ curl http://127.0.0.1:8000/api/owner/{id} and expect the following response:

      +
      [{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}]
      +
      +
      +

      Let’s first discuss the code from line 23 to 28 in server/main.go.

      +
      func main() {
      +
      +	// ...
      +	
      +	api := operations.NewCarePetAPI(spec())
      +	server := restapi.NewServer(api)
      +	defer server.Shutdown()
      +
      +	configure(server)
      +	server.ConfigureAPI()
      +
      +	// ...
      +
      +}
      +
      +
      +

      The api object represent a list of functions and codes generated by the swagger tool. Those operations are then passed to the NewServer method to configure the API and handler methods:

      +
      // ConfigureAPI configures the API and handlers.
      +func (s *Server) ConfigureAPI() {
      +	if s.api != nil {
      +		s.handler = configureAPI(s.api)
      +	}
      +}
      +
      +
      +

      One example of a handler method is the FindOwnerByID in handler/owner.go.

      +
      func FindOwnerByID(ses gocqlx.Session) operations.FindOwnerByIDHandlerFunc {
      +	return func(params operations.FindOwnerByIDParams) middleware.Responder {
      +		var owner model.Owner
      +
      +		if err := db.TableOwner.GetQuery(ses).Bind(params.ID.String()).GetRelease(&owner); err == gocql.ErrNotFound {
      +			// Returns FindOwnerByIDDefault with with status code 404
      +			return operations.NewFindOwnerByIDDefault(http.StatusNotFound)
      +		} else if err != nil {
      +			log.Println("find owner by id query: ", err)
      +			// Returns FindOwnerByIDDefault with with status code 500
      +			return operations.NewFindOwnerByIDDefault(http.StatusInternalServerError)
      +		}
      +
      +		// Return status 200 and owner information
      +		return &operations.FindOwnerByIDOK{Payload: &models.Owner{
      +			Address: owner.Address,
      +			Name:    owner.Name,
      +			OwnerID: conv.UUID(strfmt.UUID(owner.OwnerID.String())),
      +		}}
      +	}
      +}
      +
      +
      +

      Line 25 queries the owner table then saves the result in the owner object or throws a not found 404 status error.

      +

      Line 32 returns a FindOwnerByIDOK object with code status 200 and the owner’s information.

      +
      +
      +

      Resources

      + +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/build-with-java.html b/master/build-with-java.html new file mode 100644 index 00000000..1e40bd75 --- /dev/null +++ b/master/build-with-java.html @@ -0,0 +1,771 @@ + + + + + + + + + + + + + Build an IoT App with Java | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Build an IoT App with Java

      +
      +

      Architecture

      +

      In this section, we will walk you through the CarePet commands and explain the code behind them. +The project is structured as follows:

      +
        +
      • Migrate (com.carepet.Migrate) - Creates the carepet keyspace and tables.

      • +
      • Collar (com.carepet.Sensor) - Generates pet health data and pushes it into the storage.

      • +
      • Web app (com.carepet.server.App) - REST API service for tracking pets’ health state.

      • +
      +
      +
      +

      Migrate

      +

      The ./bin/migrate.sh --hosts $NODE1 --datacenter datacenter1 command executes the main function in the Migrate class located Migrate.java. The function creates the keyspace and tables used by the collar and server services.

      +

      The following code in the Migrate.java file calls the createKeyspace , createSchema , and printMetadata functions.

      +
      public static void main(String[] args) {
      +	final Config config = Config.parse(new Config(), args);
      +
      +	final Migrate client = new Migrate(config);
      +	client.createKeyspace();
      +	client.createSchema();
      +	client.printMetadata();
      +}
      +
      +
      +

      Let’s break down the code line by line.

      +

      The config object parses the arguments passed in the migrate command. In our case it’s hosts and datacenter. The hosts argument expects the IP address of one of the nodes. The datacenter argument is datacenter1 by default but could be different if you use Scylla Cloud. The command also accepts username and password arguments if required.

      +

      The createKeyspace function creates a new CqlSession, then executes the following CQL query stored in the resources/care-pet-keyspace.cql file:

      +
      public void createKeyspace() {
      +	LOG.info("creating keyspace...");
      +	try (CqlSession session = connect()) {
      +			session.execute(Config.getResource("care-pet-keyspace.cql"));
      +	}
      +}
      +
      +
      +
      CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' } AND durable_writes = TRUE;
      +
      +
      +

      The CQL query above creates a new keyspace named carepet, with NetworkTopologyStrategy as replication strategy and a replication factor of 3. +See Scylla University for more information about keyspaces and replication.

      +

      The createSchema function opens a new session with the carepet keyspace and creates the following tables in the carepet keyspace using the CQL file located in resources/care-pet-ddl.cql:

      +
        +
      • owner

      • +
      • pet

      • +
      • sensor

      • +
      • measurement

      • +
      • sensor_avg

      • +
      +
      public void createSchema() {
      +	LOG.info("creating table...");
      +	try (CqlSession session = keyspace()) {
      +	    for (String cql : Config.getResource("care-pet-ddl.cql").split(";")) {
      +		session.execute(cql);
      +	    }
      +	}
      +}
      +
      +
      +

      The printMetadata function will print the metadata related to the carepet keyspace and confirm that the tables are properly created.

      +

      You can check the database structure with:

      +
      $ docker exec -it carepet-scylla1 cqlsh
      +cqlsh> USE carepet;
      +cqlsh:carepet> DESCRIBE TABLES
      +cqlsh:carepet> DESCRIBE TABLE pet
      +
      +
      +

      You should expect the following result:

      +
      CREATE TABLE carepet.pet (
      +owner_id uuid,
      +pet_id uuid,
      +chip_id text,
      +species text,
      +breed   text,
      +color   text,
      +gender  text,
      +address text,
      +age int,
      +name text,
      +weight float,
      +PRIMARY KEY (owner_id, pet_id)
      +) WITH CLUSTERING ORDER BY (pet_id ASC)
      +AND bloom_filter_fp_chance = 0.01
      +AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
      +AND comment = ''
      +AND compaction = {'class': 'SizeTieredCompactionStrategy'}
      +AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
      +AND crc_check_chance = 1.0
      +AND dclocal_read_repair_chance = 0.1
      +AND default_time_to_live = 0
      +AND gc_grace_seconds = 864000
      +AND max_index_interval = 2048
      +AND memtable_flush_period_in_ms = 0
      +AND min_index_interval = 128
      +AND read_repair_chance = 0.0
      +AND speculative_retry = '99.0PERCENTILE';
      +
      +
      +
      +
      +

      Sensor

      +

      The sensor service simulates the collar’s activity. You can use the following command to run the sensor service:

      +
      $ mvn package
      +$ NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +$ ./bin/sensor.sh --hosts $NODE1 --datacenter datacenter1 --measure PT1M --buffer-interval PT1M
      +
      +
      +

      The above command executes Sensor.java and the following main function:

      +
      public static void main(String[] args) {
      +        final Sensor client = new Sensor(Config.parse(new SensorConfig(), args));
      +        client.save();
      +        client.run();
      +    }
      +}
      +
      +
      +

      First, we create a client object, an instance of the Sensor class. Like in the Migrate class, we parse args using the Config.parse() method to connect to the database.

      +

      In the Sensor constructor, a random ID is attributed to the owner, pet, and sensors.

      +
      public Sensor(SensorConfig config) {
      +	this.config = config;
      +
      +	this.owner = Owner.random();
      +	this.pet = Pet.random(this.owner.getOwnerId());
      +	this.sensors = new com.carepet.model.Sensor[SensorType.values().length];
      +	for (int i = 0; i < this.sensors.length; i++) {
      +			this.sensors[i] = com.carepet.model.Sensor.random(this.pet.getPetId());
      +	}
      +}
      +
      +
      +

      The client.save() method connects to the datbase and saves the generated owner, pet, and the sensors.

      +
      private void save() {
      +	try (CqlSession session = keyspace()) {
      +			// Connect to the database
      +			Mapper m = Mapper.builder(session).build();
      +
      +			LOG.info("owner = " + owner);
      +			LOG.info("pet = " + pet);
      +
      +			m.owner().create(owner);
      +			m.pet().create(pet);
      +
      +			for (com.carepet.model.Sensor s : sensors) {
      +					LOG.info("sensor = " + s);
      +
      +					m.sensor().create(s);
      +			}
      +	}
      +}
      +
      +
      +

      The client.run() generates random data and pushes it to the database. In this code, we are using PreparedStatement to define the query and BatchStatementBuilder to run multiple queries at the same time. See the [Scylla Java Driver documentation] (https://java-driver.docs.scylladb.com/stable/manual/core/statements/prepared/) for details on PreparedStatement.

      +
      private void run() {
      +	try (CqlSession session = keyspace()) {
      +			PreparedStatement statement = session.prepare("INSERT INTO measurement (sensor_id, ts, value) VALUES (?, ?, ?)");
      +			BatchStatementBuilder builder = new BatchStatementBuilder(BatchType.UNLOGGED);
      +
      +			List<Measure> ms = new ArrayList<>();
      +			Instant prev = Instant.now();
      +
      +			while (true) {
      +					while (Duration.between(prev, Instant.now()).compareTo(config.bufferInterval) < 0) {
      +							if (!sleep(config.measurement)) {
      +									return;
      +							}
      +
      +							for (com.carepet.model.Sensor s : sensors) {
      +									Measure m = readSensorData(s);
      +									ms.add(m);
      +									LOG.info(m.toString());
      +							}
      +					}
      +
      +					prev = prev.plusMillis((Duration.between(prev, Instant.now()).toMillis() / config.bufferInterval.toMillis()) * config.bufferInterval.toMillis());
      +
      +					LOG.info("pushing data");
      +					// this is simplified example of batch execution. standard
      +					// best practice is to batch values that end up in the same partition:
      +					// https://www.scylladb.com/2019/03/27/best-practices-for-scylla-applications/
      +					for (Measure m : ms) {
      +							builder = builder.addStatement(statement.bind(m.getSensorId(), m.getTs(), m.getValue()));
      +					}
      +
      +					session.execute(builder.build());
      +
      +					builder.clearStatements();
      +					ms.clear();
      +			}
      +	}
      +}
      +
      +
      +
      +
      +

      Server

      +

      The server service is a REST API for tracking the pets’ health state. The service allows you to query the database via HTTP.

      +

      Run the following commands to start the server:

      +
      $ mvn package
      +$ NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +$ ./bin/server.sh --hosts $NODE1 --datacenter datacenter1
      +
      +
      +

      In the care-pet example, run:

      +

      $ curl http://127.0.0.1:8000/api/owner/{id}.

      +

      You can expect the following response:

      +
      
      +[{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}]
      +
      +
      +
      +

      The controller is defined in ModelController.java, and implements the GET methods to access owners, pets and sensors data.

      +

      The server also aggregates the data and saves it to the database in the sensor_avg table:

      +
      
      +// saveAggregate saves the result monotonically sequentially to the database
      +private void saveAggregate(UUID sensorId, List<Float> data, int prevAvgSize, LocalDate day, LocalDateTime now) {
      +// if it's the same day, we can't aggregate current hour
      +boolean sameDate = now.getDayOfYear() == day.getDayOfYear();
      +int current = now.getHour();
      +
      +        for (int hour = prevAvgSize; hour < data.size(); hour++) {
      +            if (sameDate && hour >= current) {
      +                break;
      +            }
      +
      +            mapper.sensorAvg().create(new SensorAvg(sensorId, day, hour, data.get(hour)));
      +        }
      +    }
      +
      +
      +
      +
      +
      +

      Resources

      + +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/build-with-javascript.html b/master/build-with-javascript.html new file mode 100644 index 00000000..3b7ab59e --- /dev/null +++ b/master/build-with-javascript.html @@ -0,0 +1,1077 @@ + + + + + + + + + + + + + Build an IoT App with JavaScript | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Build an IoT App with JavaScript

      +
      +

      Architecture

      +

      In this section, we will walk you through the CarePet commands and explain the code behind them. +The project is structured as follows:

      +

      Build your first ScyllaDB Powered App - Raouf

      +
        +
      • migrate (npm run migrate) - Creates the carepet keyspace and tables.

      • +
      • collar (npm run sensor) - Generates pet health data and pushes it into the storage.

      • +
      • web app (npm run dev) - REST API service for tracking pets’ health state.

      • +
      +
      +
      +

      Code Structure and Implementation

      +

      The code package structure is as follows:

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

      Name

      Purpose

      /

      web application backend

      /api

      API spec

      /cmd

      applications executables

      /cmd/migrate

      install database schema

      /cmd/sensor

      Simulates the pet’s collar

      /config

      database configuration

      /db

      database handlers (gocql/x)

      /db/cql

      database schema

      /handler

      REST API handlers

      /model

      application models and ORM metadata

      +
      +
      +

      Quick Start

      +

      Prerequisites:

      +
        +
      • NodeJS tested with v17.0.1

      • +
      • NPM tested with v8.1.0

      • +
      • docker (not required if you use Scylla Cloud)

      • +
      • docker-compose (not required if you use Scylla Cloud)

      • +
      +

      Clone the repository and change to javascript directory:

      +
      git clone git@github.com:scylladb/care-pet.git
      +cd javascript
      +
      +
      +

      Make sure to install all NodeJS dependencies with:

      +
      $ npm install
      +
      +
      +
      +
      +

      Use ScyllaDB on your local machine

      +

      To run a local ScyllaDB cluster consisting of three nodes with +the help of docker and docker-compose execute:

      +
      $ docker-compose up -d
      +
      +
      +

      Docker-compose will spin up three nodes: carepet-scylla1, carepet-scylla2, +and carepet-scylla3. You can access them with the docker command.

      +

      Execute the following nodetool command:

      +
      $ docker exec -it carepet-scylla1 nodetool status
      +
      +
      +
      +
      +

      Migrate

      +
      +

      Run ScyllaDB on your local machine

      +

      Once all the nodes are in UN - Up Normal status, run the commands below.

      +

      The following command allows you to get the node IP address:

      +
      docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1
      +
      +
      +

      The following commands execute the migrate main function.

      +
      NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +npm run migrate -- --hosts $NODE1
      +
      +
      +

      You can check the database structure with:

      +
      docker exec -it carepet-scylla1 cqlsh
      +
      +
      +
      +
      +

      Using Scylla Cloud

      +

      If you are using Scylla Cloud, use the the following command to run the migrate service:

      +
      npm run migrate -- --hosts [NODE-IP] --username [USERNAME] --password[PASSWORD]
      +
      +
      +

      Replace the NODE-IP, USERNAME, and PASSWORD with the information provided in your cluster on https://cloud.scylladb.com.

      +
      +
      +
      +

      Output

      +

      Expected output:

      +
      2020/08/06 16:43:01 Bootstrap database...
      +2020/08/06 16:43:13 Keyspace metadata = {Name:carepet DurableWrites:true StrategyClass:org.apache.cassandra.locator.NetworkTopologyStrategy StrategyOptions:map[datacenter1:3] Tables:map[gocqlx_migrate:0xc00016ca80 measurement:0xc00016cbb0 owner:0xc00016cce0 pet:0xc00016ce10 sensor:0xc00016cf40 sensor_avg:0xc00016d070] Functions:map[] Aggregates:map[] Types:map[] Indexes:map[] Views:map[]}
      +
      +
      +

      You can check the database structure with:

      +

      docker run -it --rm --entrypoint cqlsh scylladb/scylla -u [USERNAME] -p [PASSWORD] [NODE-IP]

      +

      Note: use -u [USERNAME] and -p [PASSWORD] if you are using Scylla Cloud.

      +

      Once you connect to cqlsh, run the following commands:

      +

      #. Run DESCRIBE KEYSPACES.

      +

      Expected output:

      +
      carepet  system_schema  system_auth  system  system_distributed  system_traces
      +
      +
      +

      then,

      +
       carepet;
      +DESCRIBE TABLES
      +
      +
      +

      Expected output:

      +

      pet  sensor_avg  gocqlx_migrate  measurement  owner  sensor

      +

      #. Run DESCRIBE TABLE pet.

      +

      Expected output:

      +
      CREATE TABLE carepet.pet (
      +       owner_id uuid,
      +       pet_id uuid,
      +       address text,
      +       age int,
      +       breed text,
      +       chip_id text,
      +       color text,
      +       gender text,
      +       name text,
      +       species text,
      +       weight float,
      +       PRIMARY KEY (owner_id, pet_id)  
      +   ) WITH CLUSTERING ORDER BY (pet_id ASC)
      +       AND bloom_filter_fp_chance = 0.01
      +       AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
      +       AND comment = ''
      +       AND compaction = {'class': 'SizeTieredCompactionStrategy'}
      +       AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
      +       AND crc_check_chance = 1.0
      +       AND dclocal_read_repair_chance = 0.1
      +       AND default_time_to_live = 0
      +       AND gc_grace_seconds = 864000
      +       AND max_index_interval = 2048
      +       AND memtable_flush_period_in_ms = 0
      +       AND min_index_interval = 128
      +       AND read_repair_chance = 0.0
      +       AND speculative_retry = '99.0PERCENTILE';
      +
      +
      +

      #. Run exit to exit the cqlsh.

      +
      +

      migrate/index.js

      +

      The above commands execute the main function in the cmd/migrate/index.js. The function creates the keyspace and tables that you need to run the collar and server services.

      +

      The following code in the cmd/migrate/index.js creates a new session, then calls the create_keyspace and migrate functions.

      +
      migrate/index.js
      +
      +async function main() {
      +  // Parse the command arguments: --hosts --username and --password
      +  const options = config('migrate').parse().opts();
      +  
      +  // Create a new session with options 
      +  const client = await getClient(options);
      +
      +  // Create a keyspace
      +  await client.execute(cql.KEYSPACE);
      +  
      +  // Create the tables
      +  for (const query of cql.MIGRATE) {
      +    log.debug(`query = ${query}`);
      +    await client.execute(query);
      +  }
      +
      +  return client;
      +}
      +
      +
      +

      Let’s break down the code above.

      +

      The getClient function takes the options as a parameter and creates a new session.

      +
      // src/db.js
      +
      +async function getClient(config, keyspace) {
      +  const client = new cassandra.Client({
      +    contactPoints: config.hosts,
      +    authProvider: new cassandra.auth.PlainTextAuthProvider(
      +      config.username,
      +      config.password
      +    ),
      +    localDataCenter: 'datacenter1',
      +    keyspace,
      +  });
      +
      +  await client.connect();
      +
      +  return client;
      +}
      +
      +
      +

      await client.execute(cql.KEYSPACE); creates a keyspace as defined in cql/keyspace.cql:

      +
      CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' };
      +
      +
      +

      The CQL query above creates a new keyspace named carepet, with NetworkTopologyStrategy as replication strategy and a replication factor of 3. +See Scylla University for more information about keyspaces and replication.

      +

      Finally, the code loops through all the queries listed in cql/migrate.cql to create the tables you need for the project.

      +
      CREATE TABLE IF NOT EXISTS carepet.owner
      +(
      +    owner_id UUID,
      +    address TEXT,
      +    name    TEXT,
      +    PRIMARY KEY (owner_id)
      +);
      +
      +...
      +
      +
      +

      You can check the database structure. Connect to your local ScyllaDB instance using:

      +

      docker exec -it carepet-scylla1 cqlsh

      +

      With Scylla Cloud, use:

      +
      docker run -it --rm --entrypoint cqlsh scylladb/scylla -u [USERNAME] -p [PASSWORD] [NODE-IP]
      +
      +
      +

      Once connected to your machine, run the following commands:

      +
      cqlsh> USE carepet;
      +cqlsh:carepet> DESCRIBE TABLES
      +cqlsh:carepet> DESCRIBE TABLE pet
      +
      +
      +

      You should expect the following result:

      +
      CREATE TABLE carepet.pet (
      +    owner_id uuid,
      +    pet_id uuid,
      +    chip_id text,
      +    species text,
      +    breed   text,
      +    color   text,
      +    gender  text,
      +    address text,
      +    age int,
      +    name text,
      +    weight float,
      +    PRIMARY KEY (owner_id, pet_id)
      +) WITH CLUSTERING ORDER BY (pet_id ASC)
      +    AND bloom_filter_fp_chance = 0.01
      +    AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
      +    AND comment = ''
      +    AND compaction = {'class': 'SizeTieredCompactionStrategy'}
      +    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
      +    AND crc_check_chance = 1.0
      +    AND dclocal_read_repair_chance = 0.1
      +    AND default_time_to_live = 0
      +    AND gc_grace_seconds = 864000
      +    AND max_index_interval = 2048
      +    AND memtable_flush_period_in_ms = 0
      +    AND min_index_interval = 128
      +    AND read_repair_chance = 0.0
      +    AND speculative_retry = '99.0PERCENTILE';
      +
      +
      +
      +
      +
      +

      Sensor

      +

      The sensor service simulates the collar’s activity and periodically saves data to the database. Use the below commands to run the sensor service:

      +
      +

      Using ScyllaDB on your local machine

      +
      NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +npm run sensor -- --hosts $NODE1 --measure 5s --buffer-interval 1m
      +
      +
      +
      +
      +

      Using Scylla Cloud

      +
      npm run sensor -- --hosts [NODE-IP] --username [USERNAME] --password [PASSWORD] --measure 5s --buffer-interval 1m
      +
      +
      +

      Replace the NODE-IP, USERNAME, and PASSWORD with the information provided in your cluster on https://cloud.scylladb.com.

      +

      Expected output:

      +
      2020/08/06 16:44:33 Welcome to the Pet collar simulator
      +2020/08/06 16:44:33 New owner # 9b20764b-f947-45bb-a020-bf6d02cc2224
      +2020/08/06 16:44:33 New pet # f3a836c7-ec64-44c3-b66f-0abe9ad2befd
      +2020/08/06 16:44:33 sensor # 48212af8-afff-43ea-9240-c0e5458d82c1 type L new measure 51.360596 ts 2020-08-06T16:44:33+02:00
      +2020/08/06 16:44:33 sensor # 2ff06ffb-ecad-4c55-be78-0a3d413231d9 type R new measure 36 ts 2020-08-06T16:44:33+02:00
      +2020/08/06 16:44:33 sensor # 821588e0-840d-48c6-b9c9-7d1045e0f38c type L new measure 26.380281 ts 2020-08-06T16:44:33+02:00
      +...
      +
      +
      +

      The above command executes cmd/sensor/index.js and takes the following as arguments:

      +
        +
      • hosts : the IP address of the ScyllaDB node.

      • +
      • username: when Password Authentication enabled

      • +
      • password: when Password Authentication enabled

      • +
      • measure: the interval between to sensor measures.

      • +
      • buffer-interval: the interval between two database queries.

      • +
      +
      // sensor/index.js
      +
      +async function main() {
      +  // Parse command arguments
      +  const options = cli(config('sensor simulator'))
      +    .parse()
      +    .opts();
      +
      +  const bufferInterval = parseDuration(options.bufferInterval);
      +  const measure = parseDuration(options.measure);
      +
      +  // ...
      +  
      +  // Connect to cluster using a keyspace
      +  const client = await getClientWithKeyspace(options);
      +
      +  // Generate random owner, pet and sensors IDs
      +  const { owner, pet, sensors } = randomData();
      +
      +  await saveData(client, owner, pet, sensors);
      +
      +  // Generate sensor data and save them to the database periodically
      +  await runSensorData(
      +    client,
      +    {
      +      bufferInterval,
      +      measure,
      +    },
      +    sensors
      +  );
      +
      +  return client;
      +}
      +
      +
      +

      Just like in migrate/index.js, the function parses the npm run sensor command arguments. +Now you can create a new session client using carepet keyspace.

      +
      // db.js
      +
      +async function getClientWithKeyspace(config) {
      +  return getClient(config, KEYSPACE);
      +}
      +
      +
      +

      The saveData method connects to the database and saves random owner, pet, and sensors to the database.

      +
      // sensor/index.js
      +
      +async function saveData(client, owner, pet, sensors) {
      +  await client.execute(insertQuery(Owner), owner, { prepare: true });
      +  log.info(`New owner # ${owner.owner_id}`);
      +
      +  await client.execute(insertQuery(Pet), pet, { prepare: true });
      +  log.info(`New pet # ${pet.pet_id}`);
      +
      +  for (let sensor of sensors) {
      +    await client.execute(insertQuery(Sensor), sensor, { prepare: true });
      +    log.info(`New sensor # ${sensor.sensor_id}`);
      +  }
      +}
      +
      +
      +

      The runSensorData generates random data and inserts it to the database every buffer_interval. Note that we are inserting the data to the database using a batch.

      +
      async function runSensorData(client, { bufferInterval, measure }, sensors) {
      +  let last = moment();
      +  while (true) {
      +    const measures = [];
      +    while (moment().diff(last) < bufferInterval) {
      +      await delay(measure);
      +
      +      measures.push(
      +        ...sensors.map(sensor => {
      +          const measure = readSensorData(sensor);
      +          log.info(
      +            `sensor # ${sensor.sensor_id} type ${sensor.type} new measure ${
      +              measure.value
      +            } ts ${moment(measure.ts).toISOString()}`
      +          );
      +
      +          return measure;
      +        })
      +      );
      +    }
      +
      +    last = last.add(
      +      measure.valueOf() * (moment().diff(last).valueOf() / measure.valueOf())
      +    );
      +
      +    log.info('Pushing data');
      +
      +    const batch = measures.map(measure => ({
      +      query: insertQuery(Measure),
      +      params: measure,
      +    }));
      +
      +    await client.batch(batch, { prepare: true });
      +  }
      +}
      +
      +
      +
      +
      +
      +

      Server

      +

      The server service is a REST API for tracking the pets’ health state. The service allows you to query the database via HTTP.

      +

      Run the following commands to start the server:

      +
      +

      Using ScyllaDB on your local machine

      +
      NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +npm run dev -- --hosts $NODE1
      +
      +
      +
      +
      +

      Using Scylla Cloud

      +
      npm run dev -- --hosts [NODE-IP] --username [USERNAME] --password [PASSWORD]
      +
      +
      +

      Expected output:

      +
      2020/08/06 16:45:58 Serving care pet at http://127.0.0.1:8000
      +
      +
      +

      The src/index.js main function mounts the api on /api and defines the routes.

      +
      // src/index.js
      +
      +async function main() {
      +  const options = config('care-pet').parse().opts();
      +
      +  log.debug(`Configuration = ${JSON.stringify(options)}`);
      +
      +  const client = await getClientWithKeyspace(options);
      +
      +  app.get(owner.ROUTE, asyncHandler(owner.handler(client)));
      +  app.get(pets.ROUTE, asyncHandler(pets.handler(client)));
      +  app.get(sensors.ROUTE, asyncHandler(sensors.handler(client)));
      +  app.get(measures.ROUTE, asyncHandler(measures.handler(client)));
      +  app.get(avg.ROUTE, asyncHandler(avg.handler(client)));
      +
      +  app.listen(8000, () => {
      +    log.info('Care-pet server started on port 8000!');
      +  });
      +}
      +
      +
      +
      +
      +
      +

      Using the Application

      +

      Open a different terminal to send an HTTP request from the CLI:

      +

      curl -v http://127.0.0.1:8000/

      +

      Expected output:

      +
      > GET / HTTP/1.1
      +> Host: 127.0.0.1:8000
      +> User-Agent: curl/7.71.1
      +> Accept: */*
      +> 
      +* Mark bundle as not supporting multiuse
      +< HTTP/1.1 404 Not Found
      +< Content-Type: application/json
      +< Date: Thu, 06 Aug 2020 14:47:41 GMT
      +< Content-Length: 45
      +< Connection: close
      +< 
      +* Closing connection 0
      +{"code":404,"message":"path / was not found"}
      +
      +
      +

      The JSON with the 404 at the end indicates expected behavior. +To read an owner’s data use the previously saved owner_id as follows:

      +

      curl -v http://127.0.0.1:8000/api/owner/{owner_id}

      +

      For example:

      +

      curl http://127.0.0.1:8000/api/owner/a05fd0df-0f97-4eec-a211-cad28a6e5360

      +

      Expected result:

      +
      {"address":"home","name":"gmwjgsap","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360"} 
      +
      +
      +

      To list the owner’s pets, run:

      +

      curl -v http://127.0.0.1:8000/api/owner/{owner_id}/pets

      +

      For example:

      +

      curl http://127.0.0.1:8000/api/owner/a05fd0df-0f97-4eec-a211-cad28a6e5360/pets

      +

      Expected output:

      +

      [{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}]

      +

      To list each pet’s sensor, run:

      +

      curl -v curl -v http://127.0.0.1:8000/api/pet/{pet_id}/sensors

      +

      For example:

      +

      curl http://127.0.0.1:8000/api/pet/cef72f58-fc78-4cae-92ae-fb3c3eed35c4/sensors

      +
      [{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d","type":"L"},{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"5c70cd8a-d9a6-416f-afd6-c99f90578d99","type":"R"},{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"fbefa67a-ceb1-4dcc-bbf1-c90d71176857","type":"L"}]
      +
      +
      +

      To review the data from a specific sensor:

      +

      curl http://127.0.0.1:8000/api/sensor/{sensor_id}/values?from=2006-01-02T15:04:05Z07:00&to=2006-01-02T15:04:05Z07:00

      +

      For example:

      +

      curl http://127.0.0.1:8000/api/sensor/5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d/values\?from\="2020-08-06T00:00:00Z"\&to\="2020-08-06T23:59:59Z"

      +

      expected output:

      +

      [51.360596,26.737432,77.88015,...]

      +

      To read the pet’s daily average per sensor, use:

      +

      curl http://127.0.0.1:8000/api/sensor/{sensor_id}/values/day/{date}

      +

      For example:

      +

      curl -v http://127.0.0.1:8000/api/sensor/5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d/values/day/2020-08-06

      +

      Expected output:

      +

      [0,0,0,0,0,0,0,0,0,0,0,0,0,0,42.55736]

      +
      +
      +

      Resources

      + +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/build-with-php.html b/master/build-with-php.html new file mode 100644 index 00000000..5d1eca75 --- /dev/null +++ b/master/build-with-php.html @@ -0,0 +1,970 @@ + + + + + + + + + + + + + Care Pet ScyllaDB PHP IoT example | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Care Pet ScyllaDB PHP IoT example

      +

      This example project demonstrates a generic IoT use case for ScyllaDB in PHP.

      +

      Here you will find a list of possible drivers to integrate with.

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

      PHP Version

      Driver

      PHP 7.1

      DataStax PHP Driver

      PHP 8.2 [x]

      ScyllaDB PHP Driver (community)

      +

      You will need to build the driver following the instructions of each repository. We strongly recommend that you go for +PHP 8.x since this project still being maintained and developed by community itself.

      +

      The documentation for this application and the guided exercise is here.

      +
      +

      Quick Start

      +

      The application allows the tracking of the pets health indicators and it consist in a CLI of three parts:

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

      Command

      Description

      php scylla migrate

      creates the carepet keyspace and tables

      php scylla simulate

      generates a pet health data and pushes it into the storage

      php scylla serve

      REST API service for tracking pets health state

      +

      Prerequisites:

      + +
      +
      +

      Setup

      +

      To run a local ScyllaDB cluster consisting of three nodes and the PHP Environment with +the help of docker and docker-compose execute:

      +
      $ docker-compose up -d
      +
      +
      +

      Docker-compose will spin up three nodes which are:

      +
        +
      • carepet-scylla1

      • +
      • carepet-scylla2

      • +
      • carepet-scylla3

      • +
      +

      If you want to see your containers running, run the docker ps command, and you should see something like this:

      +
      $ docker ps
      +CONTAINER ID   IMAGE                    COMMAND                  CREATED       STATUS       PORTS                                                                      NAMES
      +4e351dfe3987   scylladb/scylla          "/docker-entrypoint.…"   1 minute ago   Up 1 minute   22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp   carepet-scylla2
      +9e7e4d3992df   scylladb/scylla          "/docker-entrypoint.…"   1 minute ago   Up 1 minute   22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp   carepet-scylla3
      +7e2b1b94389b   scylladb/scylla          "/docker-entrypoint.…"   1 minute ago   Up 1 minute   22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp   carepet-scylla1
      +
      +
      +
      +

      If you have any error regarding “premature connection”, restart your docker instance and wait a minute until +your ScyllaDB connection be established.

      +
      +
      +

      Useful Commands

      +

      Here’s a list of everything that you can execute and make your own research through the application.

      +
      +

      PHP Application Commands

      +

      These commands you can execute by entering the container or through docker exec remotely:

      +
      +
      Configuring the Environment
      +

      Make a copy of .env.example and name it .env. This file will store your application secrets.

      +
      $ cp .env.example .env
      +
      +
      +

      By default, the config to connect on your local ScyllaDB instances will be ready to use.

      +
      # Development
      +DB_KEYSPACE="carepet"
      +DB_NODES="localhost"
      +DB_USERNAME=""
      +DB_PASSWORD=""
      +DB_PORT=9042
      +
      +# Production (Cloud)
      +#DB_KEYSPACE="carepet"
      +#DB_NODES="node-0.aws_sa_east_1.c106d1ac5f3117a20bf0.clusters.scylla.cloud"
      +#DB_USERNAME="scylla"
      +#DB_PASSWORD="p50bonFq8cuxwXS"
      +#DB_PORT=9042
      +
      +
      +
      +

      If you want to use ScyllaDB Cloud, remember to change at your keyspace the Replication Factor related to +for each environment.

      +
      +
      +
      +
      Initializing Keyspace:
      +

      First, let’s create our keyspace using CQLSH.

      +
      $ docker exec -it carepet-scylla1 cqlsh
      +Connected to  at 10.10.5.2:9042.
      +[cqlsh 5.0.1 | Cassandra 3.0.8 | CQL spec 3.3.1 | Native protocol v4]
      +Use HELP for help.
      +cqlsh> CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '2' };
      +cqlsh>
      +
      +
      +

      Then you can run the CLI command to migrate all your tables inside the keyspace.

      +
      $ php scylla migrate
      +[INFO] Fetching Migrations... 
      +[INFO] Migrated: /var/www/migrations/1-create_keyspace.cql 
      +[INFO] Migrated: /var/www/migrations/2-create_owner_table.cql 
      +[INFO] Migrated: /var/www/migrations/3-create_pets_table.cql 
      +[INFO] Migrated: /var/www/migrations/4-create_sensors_table.cql 
      +[INFO] Migrated: /var/www/migrations/5-create_measurements_table.cql 
      +[INFO] Migrated: /var/www/migrations/6-create_sensor_avg_table.cql 
      +[INFO] Done :D 
      +
      +
      +
      +
      +
      Starting Web Server:
      +
      $ php scylla serve
      +[INFO] CarePet Web started!
      +[INFO] Development Server: http://0.0.0.0:8000
      +[Thu Jan  5 17:32:01 2023] PHP 7.4.33 Development Server (http://0.0.0.0:8000) started
      +
      +
      +
      +
      +
      Simulate Environment Sensors:
      +
      $ php scylla simulate
      +[INFO] Starting Sensor simulator... 
      +[INFO] Batch: 0
      +[INFO] Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1 
      +[INFO] Pet: 14d9f304-5600-34af-8622-3d4505d617d7 | Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1
      +[INFO] Sensor: 869bd01e-e0ba-364f-bbfb-8c7c496a3318 (R) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
      +[INFO] Sensor: c86f63b0-1439-3404-8750-b71b90a685cb (L) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
      +[INFO] Sensor: e0550426-8832-3d17-9025-77726b3009c5 (P) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
      +[INFO] Sensor: bf960c81-8e0f-3012-b50d-18596b50db18 (P) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
      +[INFO] Sensor: 933245de-812e-34e4-8d50-2ab072726217 (T) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
      +[INFO] Pet: 319ec566-d6b0-3868-ac5e-76253ee7c236 | Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1
      +[INFO] ...
      +
      +
      +
      final class SimulateCommand extends AbstractCommand
      +{
      +
      +    public function __construct(
      +        private readonly OwnerRepository $ownerRepository,
      +        private readonly PetRepository    $petRepository,
      +        private readonly SensorRepository $sensorRepository
      +    )
      +    {
      +    }
      +
      +    const AMOUNT_BASE = 50000;
      +
      +    public function __invoke(array $args = []): int
      +    {
      +        $this->info('Starting Sensor simulator...');
      +        foreach (range(0, self::AMOUNT_BASE) as $i) {
      +            $this->info("Batch: " . $i);
      +            [$ownerDTO, $petsDTO] = $this->generateFakeData();
      +
      +            $this->ownerRepository->create($ownerDTO);
      +            $this->info(sprintf('Owner %s', $ownerDTO->id));
      +
      +            $petsDTO->each(function ($petDTO) {
      +                $this->info(sprintf('Pet: %s | Owner %s', $petDTO->id->uuid(), $petDTO->ownerId));
      +                $this->petRepository->create($petDTO);
      +
      +                SensorFactory::makeMany(5, ['pet_id' => $petDTO->id])
      +                    ->each($this->handleSensors());
      +            });
      +        }
      +        $this->info('Done :D');
      +
      +        return self::SUCCESS;
      +    }
      +
      +    private function generateFakeData(): array
      +    {
      +        $ownerDTO = OwnerFactory::make();
      +        $petsDTO = PetFactory::makeMany(5, ['owner_id' => $ownerDTO->id]);
      +
      +        return [$ownerDTO, $petsDTO];
      +    }
      +
      +    private function handleSensors(): Closure
      +    {
      +        return function (SensorDTO $sensorDTO) {
      +            $this->sensorRepository->create($sensorDTO);
      +            $this->info(sprintf(
      +                'Sensor: %s (%s) | Pet %s',
      +                $sensorDTO->id,
      +                $sensorDTO->type->name,
      +                $sensorDTO->petId
      +            ));
      +        };
      +    }
      +}
      +
      +
      +
      +
      +
      Inserting Data
      +

      You can use Cassandra::cluster() and setup your cluster.

      +
      use Cassandra;
      +use Cassandra\Cluster;
      +use Cassandra\Cluster\Builder;
      +use Cassandra\FutureRows;
      +use Cassandra\Session;
      +use Cassandra\SimpleStatement;
      +
      +class Connector
      +{
      +    public Builder $connectionBuilder;
      +    public Cluster $cluster;
      +    public Session $session;
      +    public SimpleStatement $query;
      +
      +    const BASE_TIMEOUT = 10;
      +
      +    public function __construct(array $config)
      +    {
      +        $this->connectionBuilder = Cassandra::cluster()
      +            ->withContactPoints($config['nodes'])
      +            ->withDefaultConsistency($config['consistency_level'])
      +            ->withPort($config['port']);
      +
      +        if (!empty($config['username'] && !empty($config['password']))) {
      +            $this->connectionBuilder = $this->connectionBuilder->withCredentials($config['username'], $config['password']);
      +        }
      +        $this->cluster = $this->connectionBuilder->build();
      +
      +        $this->session = $this->cluster->connect($config['keyspace']);
      +    }
      +
      +    public function setKeyspace(string $keyspace = ''): self
      +    {
      +        $this->session->close(self::BASE_TIMEOUT);
      +        $this->session = $this->cluster->connect($keyspace);
      +
      +        return $this;
      +    }
      +
      +    public function prepare(string $query): self
      +    {
      +        $this->query = new SimpleStatement($query);
      +
      +        return $this;
      +    }
      +
      +    public function execute(): FutureRows
      +    {
      +        return $this->session->executeAsync($this->query, []);
      +    }
      +}
      +
      +
      +
      use App\Core\Entities\AbstractDTO;
      +use Cassandra\Rows;
      +
      +abstract class AbstractRepository
      +{
      +    public string $table = '';
      +
      +    public string $primaryKey = '';
      +
      +    public Connector $connection;
      +
      +    public array $keys = [];
      +
      +    public function __construct(Connector $connector)
      +    {
      +        $this->connection = $connector;
      +    }
      +
      +    public function getById(string $id): Rows
      +    {
      +        $query = sprintf("SELECT * FROM %s WHERE %s = %s", $this->table, $this->primaryKey, $id);
      +
      +        return $this->connection
      +            ->prepare($query)
      +            ->execute()
      +            ->get(Connector::BASE_TIMEOUT);
      +    }
      +
      +    public function all(): Rows
      +    {
      +        return $this->connection
      +            ->prepare(sprintf('SELECT * FROM %s', $this->table))
      +            ->execute()
      +            ->get(Connector::BASE_TIMEOUT);
      +    }
      +
      +    public function create(AbstractDTO $dto): void
      +    {
      +        $keys = array_keys($dto->toDatabase());
      +        $dataValues = array_values($dto->toDatabase());
      +
      +        foreach ($dataValues as $key => $value) {
      +            if (is_string($value) && !in_array($keys[$key], $this->keys)) {
      +                $value = addslashes($value);
      +                $dataValues[$key] = "'$value'";
      +            }
      +        }
      +
      +        $query = sprintf(
      +            "INSERT INTO %s (%s) VALUES (%s)",
      +            $this->table,
      +            implode(', ', $keys),
      +            implode(', ', $dataValues)
      +        );
      +
      +
      +        $this->connection
      +            ->prepare($query)
      +            ->execute();
      +    }
      +}
      +
      +
      +
      +
      +
      +

      ScyllaDB Commands

      +
      +
      Running Nodetool:
      +
      $ docker exec -it carepet-scylla1 nodetool status
      +=======================
      +Datacenter: datacenter1
      +=======================
      +Status=Up/Down
      +|/ State=Normal/Leaving/Joining/Moving
      +--  Address    Load       Tokens       Owns    Host ID                               Rack
      +UN  10.10.5.2  212 KB     256          ?       f6121e15-48df-4b31-b725-3ad2795b8b94  rack1
      +UN  10.10.5.3  1.06 MB    256          ?       871795f3-67d2-47ba-83ef-15714b89c02a  rack1
      +UN  10.10.5.4  1.06 MB    256          ?       cbe74a63-2cf4-41c2-bf7f-c831c0d2689f  rack1
      +
      +
      +
      +
      +
      Running Container Shell:
      +
      $ docker exec -it carepet-scylla1 bash
      +
      +   _____            _ _       _____  ____
      +  / ____|          | | |     |  __ \|  _ \
      + | (___   ___ _   _| | | __ _| |  | | |_) |
      +  \___ \ / __| | | | | |/ _` | |  | |  _ <
      +  ____) | (__| |_| | | | (_| | |__| | |_) |
      + |_____/ \___|\__, |_|_|\__,_|_____/|____/
      +               __/ |
      +              |___/
      +Nodetool:
      +        nodetool help
      +CQL Shell:
      +        cqlsh
      +More documentation available at:
      +        http://www.scylladb.com/doc/
      +
      +root@7e2b1b94389b:/#
      +
      +
      +
      +
      +
      Inspecting a Container
      +

      You can inspect any node by means of the docker inspect command as follows. For example:

      +
      $ docker inspect carepet-scylla1
      +[
      +    {
      +        "Id": "7e2b1b94389b36c494093db8e119c2b8c5167339f20e03d9bfa070e8e46f8430",
      +        "Created": "2023-01-05T17:36:59.038609825Z",
      +        "Path": "/docker-entrypoint.py",
      +        "Args": [
      +            "--smp",
      +            "1"
      +        ],
      +        "State": {
      +            "Status": "running",
      +            "Running": true,
      +            "Paused": false,
      +            "Restarting": false
      +            ...
      +        }
      +    }
      +]
      +
      +
      +
      +
      Get Node IP Address:
      +
      $ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1
      +10.10.5.2
      +
      +
      +
      +
      +
      +
      +
      +

      Resources

      + +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/build-with-python.html b/master/build-with-python.html new file mode 100644 index 00000000..9b43f1dc --- /dev/null +++ b/master/build-with-python.html @@ -0,0 +1,778 @@ + + + + + + + + + + + + + Build an IoT App with Python | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Build an IoT App with Python

      +
      +

      Architecture

      +

      This section will walk through and explain the code for the different commands. +As explained in the Getting Started page, the project is structured as follow:

      +
        +
      • Migrate (python src/migrate.py) - creates keyspace and tables in ScyllaDB

      • +
      • Sensor (python src/sensor.py) - generates random IoT data and inserts it into ScyllaDB

      • +
      • API (python src/api.py) - REST API service to fetch data from ScyllaDB

      • +
      +
      +
      +

      Clone repository and install dependencies

      +

      Clone the repository and open the root directory of the project:

      +
      git clone https://github.com/scylladb/care-pet
      +cd care-pet/python
      +
      +
      +

      Create a new virtual environment and activate it:

      +
      virtualenv env
      +source env/bin/activate
      +
      +
      +

      Install all Python dependencies:

      +
      pip install -r requirements.txt
      +
      +
      +
      +
      +

      Start Docker containers (skip this if you use Scylla Cloud)

      +

      Spin up a local ScyllaDB cluster with three nodes using docker and docker-compose:

      +
      docker-compose up -d
      +
      +Creating carepet-scylla3 ... done
      +Creating carepet-scylla2 ... done
      +Creating carepet-scylla1 ... done
      +
      +
      +

      This command starts three ScyllaDB nodes in containers:

      +
        +
      • carepet-scylla1

      • +
      • carepet-scylla2

      • +
      • carepet-scylla3

      • +
      +

      You can inspect any of these nodes by using the docker inspect command, +for example:

      +
      docker inspect carepet-scylla1
      +
      +[
      +    {
      +        "Id": "c87128b7d0ca4a31a84da78875c8b4181283c34783b6b0a78bffbacbbe45fcc2",
      +        "Created": "2023-01-08T21:17:13.212585687Z",
      +        "Path": "/docker-entrypoint.py",
      +        "Args": [
      +            "--smp",
      +            "1"
      +        ],
      +        "State": {
      +            "Status": "running",
      +            "Running": true,
      +...
      +
      +
      +
      +
      +

      Connect to ScyllaDB and create the database schema

      +

      To connect to your ScyllaDB storage within the container, you need to know the +IP address of one of the running nodes. +This is how you can get the IP address of the first node running in the container:

      +
      docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1
      +
      +
      +

      You will need to reference this value multiple times later so if it’s easier +for you can save it as a variable NODE1:

      +
      NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +
      +
      +

      Now you can run the migration script that creates the required keyspace and tables:

      +
      python src/migrate.py -h $NODE1
      +
      +Creating keyspace...
      +Done.
      +Migrating database...
      +Done.
      +
      +
      +

      See the database schema using cqlsh in the container:

      +
      docker exec -it carepet-scylla1 cqlsh
      +cqlsh> DESCRIBE KEYSPACES;
      +
      +carepet        system_auth  system_distributed_everywhere  system_traces
      +system_schema  system       system_distributed 
      +
      +cqlsh> USE carepet;
      +cqlsh:carepet> DESCRIBE TABLES;
      +
      +owner  pet  sensor  sensor_avg  measurement
      +
      +cqlsh:carepet> DESCRIBE TABLE pet;
      +
      +CREATE TABLE carepet.pet (
      +    owner_id uuid,
      +    pet_id uuid,
      +    address text,
      +    age int,
      +    name text,
      +    weight float,
      +    PRIMARY KEY (owner_id, pet_id)
      +) WITH CLUSTERING ORDER BY (pet_id ASC)
      +    AND bloom_filter_fp_chance = 0.01
      +    AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
      +    AND comment = ''
      +    AND compaction = {'class': 'SizeTieredCompactionStrategy'}
      +    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
      +    AND crc_check_chance = 1.0
      +    AND dclocal_read_repair_chance = 0.0
      +    AND default_time_to_live = 0
      +    AND gc_grace_seconds = 864000
      +    AND max_index_interval = 2048
      +    AND memtable_flush_period_in_ms = 0
      +    AND min_index_interval = 128
      +    AND read_repair_chance = 0.0
      +    AND speculative_retry = '99.0PERCENTILE';
      +
      +cqlsh:carepet> exit;
      +
      +
      +

      At this point you have ScyllaDB running with the correct keyspace and tables.

      +
      +
      +

      Generate and ingest IoT data

      +

      Start ingesting IoT data (it’s suggested to do this in a new separate terminal +because this process runs indefinitely). Make sure you’re still in the virtual +environment:

      +
      source env/bin/activate
      +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +python src/sensor.py -h $NODE1 --measure 2 --buffer-interval 10
      +
      +Welcome to the Pet collar simulator
      +New owner # 1cfbc0e5-6b05-476d-b170-2660cf40c02a
      +New pet # 1a0800ee-7643-4794-af7b-2ecaaf7078fc
      +New sensor(0) # b6155934-bd4e-47de-8649-1fad447aa036
      +New sensor(1) # d2c62c4d-9621-469d-b62c-41ef2271fca7
      +sensor # b6155934-bd4e-47de-8649-1fad447aa036 type T, new measure: 100.55118431400851, ts: 2023-01-08 17:36:17.126374
      +sensor # d2c62c4d-9621-469d-b62c-41ef2271fca7 type L, new measure: 37.486651732296835, ts: 2023-01-08 17:36:17.126516
      +
      +
      +

      This command starts a script that generates and ingests random IoT data coming +from two sensors every other second and inserts the data in batches +every ten seconds. Whenever you see Pushing data in the command line that is +when data actually gets insterted into ScyllaDB.

      +

      Optional: You can modify the frequency of the generated data by changing the +--measure and --buffer-interval arguments. For example, +you can generate new data points every three seconds and insert the batches +every 30 seconds:

      +
      source env/bin/activate
      +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +python src/sensor.py -h $NODE1 --measure 3 --buffer-interval 30
      +
      +
      +

      You can run multiple ingestion processes in parallel if you wish.

      +
      +
      +

      Set up and test REST API

      +

      In a new terminal, start running the API server (make sure that port 8000 is free):

      +
      source env/bin/activate
      +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +python src/api.py -h $NODE1
      +
      +INFO:     Started server process [696274]
      +INFO:     Waiting for application startup.
      +INFO:     Application startup complete.
      +INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
      +
      +
      +

      The API server is running on http://127.0.0.1:8000. Test with your +browser, or curl, if it works properly:

      +
      curl http://127.0.0.1:8000
      +
      +{"message":"Pet collar simulator API"}
      +
      +
      +

      Next, you will test the following API endpoints:

      +
        +
      • /api/owner/{owner_id}

        +

        Returns all available data fields about the owner.

        +
      • +
      • /api/owner/{owner_id}/pets

        +

        Returns the owner’s pets.

        +
      • +
      • /api/pet/{pet_id}/sensors

        +

        Returns all the sensors of a pet.

        +
      • +
      +

      To test these endpoints, you need to provide either an owner_id or a pet_id +as URL path parameter. You can get these values by copying them from the +beginning of output of the ingestion script:

      +
      source env/bin/activate
      +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +python src/sensor.py -h $NODE1 --measure 1 --buffer-interval 6
      +
      +Welcome to the Pet collar simulator
      +New owner # 1cfbc0e5-6b05-476d-b170-2660cf40c02a <-- This is what you need!
      +New pet # 1a0800ee-7643-4794-af7b-2ecaaf7078fc <-- This is what you need!
      +New sensor(0) # b6155934-bd4e-47de-8649-1fad447aa036
      +New sensor(1) # d2c62c4d-9621-469d-b62c-41ef2271fca7
      +
      +
      +

      Copy the UUID values right after “New owner #” and “New pet #”. A UUID value +looks like this:

      +
      1cfbc0e5-6b05-476d-b170-2660cf40c02a
      +
      +
      +

      /api/owner/{owner_id}

      +

      Paste the owner id from the terminal into the endpoint URL and open it with +your browser or use curl, for example:

      +
      curl http://127.0.0.1:8000/api/owner/4f42fb80-c209-4d19-8c43-daf554f1be23
      +
      +{"owner_id":"4f42fb80-c209-4d19-8c43-daf554f1be23","address":"home","name":"Vito Russell"}
      +
      +
      +

      /api/owner/{owner_id}/pets

      +

      Use the same owner id value to test this endpoint, for example:

      +
      curl http://127.0.0.1:8000/api/owner/4f42fb80-c209-4d19-8c43-daf554f1be23/pets
      +
      +[{"owner_id":"4f42fb80-c209-4d19-8c43-daf554f1be23","pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","address":"home","age":20,"name":"Duke","weight":14.41481876373291}]
      +
      +
      +

      /api/pet/{pet_id}/sensors

      +

      Finally, use a pet id to test this endpoint, for example:

      +
      curl http://127.0.0.1:8000/api/pet/44f1624e-07c2-4971-85a5-85b9ad1ff142/sensors
      +
      +[{"pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","sensor_id":"4bb1d214-712b-453b-b53a-ac5d4df4a1f8","type":"T"},{"pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","sensor_id":"e81915d6-1155-45e4-9174-c58e4cb8cecf","type":"L"}]
      +
      +
      +
      +
      +

      Resources

      + +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/build-with-rust.html b/master/build-with-rust.html new file mode 100644 index 00000000..30b596c5 --- /dev/null +++ b/master/build-with-rust.html @@ -0,0 +1,914 @@ + + + + + + + + + + + + + Build an IoT App with Rust | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Build an IoT App with Rust

      +
      +

      Architecture

      +

      This section will walk through and explain the code for the different commands. +As explained in the Getting Started page, the project is structured as follow:

      +
        +
      • migrate (/bin/migrate/main.rs) - creates the carepet keyspace and tables

      • +
      • collar (/bin/sensor/main.rs) - generates a pet health data and pushes it into the storage

      • +
      • web app (/main.rs) - REST API service for tracking pets health state

      • +
      +
      +
      +

      Migrate

      +

      Start by creating a local ScyllaDB cluster consisting of 3 nodes:

      +
      docker-compose up -d
      +
      +
      +

      Docker-compose will spin up a ScyllaDB cluster consisting of 3 nodes (carepet-scylla1, carepet-scylla2 and carepet-scylla3) along with the app (for example go-app) container. Wait for about two minutes and check the status of the cluster: To check the status of the cluster:

      +
      docker exec -it carepet-scylla1 nodetool status
      +
      +
      +

      Once all the nodes are in UN - Up Normal status, run the below commands:

      +

      The below command allows you to get node IP address:

      +
      docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1
      +
      +
      +

      The run the following commands to execute the migrate main function.

      +
      NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +cargo run --bin migrate -- --hosts $NODE1
      +
      +
      +

      The command executes the main function in the bin/migrate/main.rs. The function creates the keyspace and tables that you need to run the collar and server services.

      +

      The below code in the bin/migrate/main.rs creates a new session then calls the create_keyspace , migrate functions.

      +
      // migrate/main.rs
      +
      +async fn main() -> Result<()> {
      +    care_pet::log::init();
      +
      +    let app = App::from_args();
      +    debug!("Configuration = {:?}", app);
      +
      +    info!("Bootstrapping database...");
      +
      +    let sess = db::new_session(&app.db_config).await?;
      +
      +    db::create_keyspace(&sess).await?;
      +    db::migrate(&sess).await?;
      +
      +    Ok(())
      +}
      +
      +
      +

      The new_session function takes the config as a parameter and uses SessionBuilder class to crete a new session.

      +
      // db/mod.rs
      +
      +pub async fn new_session(config: &Config) -> Result<Session> {
      +    info!("Connecting to {}", config.hosts.join(", "));
      +
      +    SessionBuilder::new()
      +        .known_nodes(&config.hosts)
      +        .connection_timeout(config.timeout.into())
      +        .user(
      +            config.username.clone().unwrap_or_default(),
      +            config.password.clone().unwrap_or_default(),
      +        )
      +        .build()
      +        .await
      +        .map_err(From::from)
      +}
      +
      +
      +

      For more information about creating a new session with the Rust Driver, please have a look at the docs.

      +

      create_keyspace function takes a session as an argument and creates a keyspace as defined in db/keyspace.cql:

      +
      CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' };
      +
      +
      +

      The CQL query above creates a new keyspace named carepet, with NetworkTopologyStrategy as replication strategy and a replication factor of 3. +More information about keyspace and replication on Scylla University.

      +

      Finally, migrate will execute the queries listed in db/migrate.cql to create the tables you need for the project.

      +
      CREATE TABLE IF NOT EXISTS carepet.owner
      +(
      +    owner_id UUID,
      +    address TEXT,
      +    name    TEXT,
      +    PRIMARY KEY (owner_id)
      +);
      +
      +...
      +
      +
      +

      You can check the database structure with:

      +
      docker exec -it carepet-scylla1 cqlsh
      +cqlsh> USE carepet;
      +cqlsh:carepet> DESCRIBE TABLES
      +cqlsh:carepet> DESCRIBE TABLE pet
      +
      +
      +

      You should expect the following result:

      +
      CREATE TABLE carepet.pet (
      +    owner_id uuid,
      +    pet_id uuid,
      +    chip_id text,
      +    species text,
      +    breed   text,
      +    color   text,
      +    gender  text,
      +    address text,
      +    age int,
      +    name text,
      +    weight float,
      +    PRIMARY KEY (owner_id, pet_id)
      +) WITH CLUSTERING ORDER BY (pet_id ASC)
      +    AND bloom_filter_fp_chance = 0.01
      +    AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
      +    AND comment = ''
      +    AND compaction = {'class': 'SizeTieredCompactionStrategy'}
      +    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
      +    AND crc_check_chance = 1.0
      +    AND dclocal_read_repair_chance = 0.1
      +    AND default_time_to_live = 0
      +    AND gc_grace_seconds = 864000
      +    AND max_index_interval = 2048
      +    AND memtable_flush_period_in_ms = 0
      +    AND min_index_interval = 128
      +    AND read_repair_chance = 0.0
      +    AND speculative_retry = '99.0PERCENTILE';
      +
      +
      +
      +
      +

      Sensor

      +

      The sensor service simulates the collar’s activity and periodically saves data to the database. Use the below commands to run the sensor service:

      +
      NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +cargo run --bin sensor -- --hosts $NODE1 --measure 5s --buffer-interval 1m
      +
      +
      +

      The above command executes bin/sensor/main.rs and and takes the following as arguments.

      +
        +
      • hosts : the IP address of the ScyllaDB node.

      • +
      • measure: the interval between to sensor measures.

      • +
      • buffer-interval: the interval between two database queries.

      • +
      +
      // sensor/main.rs
      +
      +#[tokio::main]
      +async fn main() -> Result<()> {
      +    care_pet::log::init();
      +
      +    let app = App::from_args();
      +    debug!("Configuration = {:?}", &app);
      +
      +    info!("Welcome to the Pet collar simulator");
      +
      +    let sess = db::new_session_with_keyspace(&app.db_config).await?;
      +
      +    let (owner, pet, sensors) = random_data();
      +    save_data(&sess, &owner, &pet, &sensors).await?;
      +    run_sensor_data(&app, &sess, sensors).await?;
      +
      +    Ok(())
      +}
      +
      +
      +

      The app object contains the command’s arguments listed above. +We then create a new session sess using new_session_with_keyspace function defined in db/mod.rs:

      +
      // db/mod.rs
      +
      +pub async fn new_session_with_keyspace(config: &Config) -> Result<Session> {
      +    let session = new_session(config).await?;
      +    session.use_keyspace(KEYSPACE, true).await?;
      +    Ok(session)
      +}
      +
      +
      +

      The save_data method connects to the datbase and saves random owner, pet and the sensors to the database using insert_query macro defined in src/mod.rs.

      +
      // sensor/main.rs
      +
      +async fn save_data(sess: &Session, owner: &Owner, pet: &Pet, sensors: &[Sensor]) -> Result<()> {
      +    sess.query(insert_query!(Owner), owner).await?;
      +    info!("New owner # {}", owner.owner_id);
      +
      +    sess.query(insert_query!(Pet), pet).await?;
      +    info!("New pet # {}", pet.pet_id);
      +
      +    for sensor in sensors {
      +        sess.query(insert_query!(Sensor), sensor).await?;
      +    }
      +
      +    Ok(())
      +}
      +
      +
      +

      The run_sensor_data generates random data and inserts it to the database every buffer_interval.

      +
      async fn run_sensor_data(cfg: &App, sess: &Session, sensors: Vec<Sensor>) -> Result<()> {
      +    let measure: time::Duration = cfg.measure.into();
      +    let buffer_interval: time::Duration = cfg.buffer_interval.into();
      +
      +    let mut last = Instant::now();
      +    loop {
      +        let mut measures = vec![];
      +        while last.elapsed() < buffer_interval {
      +            sleep(measure).await;
      +
      +            for sensor in &sensors {
      +                let measure = read_sensor_data(sensor);
      +                info!(
      +                    "sensor # {} type {} new measure {} ts {}",
      +                    sensor.sensor_id,
      +                    sensor.r#type.as_str(),
      +                    &measure.value,
      +                    measure.ts.format_rfc3339(),
      +                );
      +
      +                measures.push(measure);
      +            }
      +        }
      +
      +        last = last
      +            + time::Duration::from_nanos(
      +                (measure.as_nanos() * (last.elapsed().as_nanos() / measure.as_nanos())) as u64,
      +            );
      +
      +        info!("Pushing data");
      +
      +        let batch = measures.iter().fold(Batch::default(), |mut batch, _| {
      +            batch.append_statement(insert_query!(Measure));
      +            batch
      +        });
      +
      +        sess.batch(&batch, measures)
      +            .await
      +            .map_err(|err| error!("execute batch query {:?}", err))
      +            .ok();
      +    }
      +}
      +
      +
      +
      +
      +

      Server

      +

      The server service is a REST API for tracking the pets’ health state. The service was built using Rocket and allows users to query the database via HTTP.

      +

      Run the following commands to start the server:

      +
      NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
      +cargo run -- --hosts $NODE1
      +
      +
      +

      The src/main.rs main function mounts the api on /api and defines the routes.

      +
      // src/main.rs
      +
      +#[rocket::main]
      +async fn main() -> Result<()> {
      +    care_pet::log::init();
      +
      +    let app = App::from_args();
      +    if app.verbose {
      +        info!("Configuration = {:?}", app);
      +    }
      +
      +    let sess = db::new_session_with_keyspace(&app.db_config).await?;
      +
      +    rocket::build()
      +        .mount(
      +            "/api",
      +            routes![
      +                handler::measures::find_sensor_data_by_sensor_id_and_time_range,
      +                handler::owner::find_owner_by_id,
      +                handler::pets::find_pets_by_owner_id,
      +                handler::sensors::find_sensors_by_pet_id,
      +                handler::avg::find_sensor_avg_by_sensor_id_and_day
      +            ],
      +        )
      +        .manage(sess)
      +        .launch()
      +        .await
      +        .map_err(From::from)
      +}
      +
      +
      +

      The handlers can be found in the src/handler folder for each route.

      +

      Let’s have a look at handler/mesure.rs file:

      +
      #[get("/sensor/<id>/values?<from>&<to>")]
      +pub async fn find_sensor_data_by_sensor_id_and_time_range(
      +    session: &State<Session>,
      +    id: UuidParam,
      +    from: DateTimeParam,
      +    to: DateTimeParam,
      +) -> Result<Json<Vec<f32>>, JsonError> {
      +    let rows = session
      +        .query(
      +            format!(
      +                "SELECT {} FROM {} WHERE {} = ? and {} >= ? and {} <= ?",
      +                Measure::FIELD_NAMES.value,
      +                Measure::table(),
      +                Measure::FIELD_NAMES.sensor_id,
      +                Measure::FIELD_NAMES.ts,
      +                Measure::FIELD_NAMES.ts,
      +            ),
      +            (id.0, from.0, to.0),
      +        )
      +        .await
      +        .map_err(|err| json_err(Status::InternalServerError, err))?
      +        .rows
      +        .unwrap_or_default()
      +        .into_typed::<(f32,)>();
      +
      +    let values = rows
      +        .map(|v| v.map(|v| v.0))
      +        .collect::<Result<Vec<_>, _>>()
      +        .map_err(|err| json_err(Status::InternalServerError, err))?;
      +
      +    Ok(Json(values))
      +}
      +
      +
      +

      The GET request on URL /sensor/<id>/values?<from>&<to> triggers find_sensor_data_by_sensor_id_and_time_range function.

      +

      find_sensor_data_by_sensor_id_and_time_range takes session, id, from and to as params. The function runs a SELECT query then returns rows.

      +
      +
      +

      Retrieving informations from API

      +

      To test out the API in your terminal, use the following command to retrieve informations of a specific pet owner:

      +
      curl http://127.0.0.1:8000/owner/{id}
      +
      +
      +
      +

      If you don’t have an owner_id, run the sensor command and it will generate users and pets on your terminal.

      +
      +

      and you should receive a response similar to this:

      +
      {
      +  "owner_id": "5b5a7b4d-a2c0-48b0-91e1-de6a5b37c923",
      +  "address": "home",
      +  "name": "sedtdkaa"
      +}
      +
      +
      +

      If you want to list owner’s pets you can use the following command:

      +
      curl http://127.0.0.1:8000/owner/{id}/pets
      +
      +
      +

      and you should receive a response similar to this:

      +
      [
      +  {
      +    "owner_id": "5b5a7b4d-a2c0-48b0-91e1-de6a5b37c923",
      +    "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999",
      +    "chip_id": null,
      +    "species": "dog",
      +    "breed": "golden-retriever",
      +    "color": "black",
      +    "gender": "M",
      +    "age": 4,
      +    "weight": 9.523097,
      +    "address": "awesome-address",
      +    "name": "doggo"
      +  }
      +]
      +
      +
      +

      If you want to list the active pet sensors you can use the following command:

      +
      curl http://127.0.0.1:8000/pet/{pet_id}/sensors
      +
      +
      +

      and you should receive a response similar to this:

      +
      [
      +  {
      +    "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999",
      +    "sensor_id": "7a8b3831-0512-4501-90f2-700c7133aeed",
      +    "type": "T"
      +  },
      +  {
      +    "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999",
      +    "sensor_id": "81250bab-cf1c-4c7a-84f1-b291a0f325ef",
      +    "type": "P"
      +  },
      +  {
      +    "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999",
      +    "sensor_id": "a22a2fdb-4aad-4abe-b0d9-381aa07a26af",
      +    "type": "L"
      +  }
      +]
      +
      +
      +
      +
      +

      Resources

      + +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/deploy-in-cloud.html b/master/deploy-in-cloud.html new file mode 100644 index 00000000..e18e219c --- /dev/null +++ b/master/deploy-in-cloud.html @@ -0,0 +1,603 @@ + + + + + + + + + + + + + Deploy in ScyllaDB Cloud with Terraform | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Deploy in ScyllaDB Cloud with Terraform

      +

      ScyllaDB Cloud has a Terraform provider which means that you can spin up new +ScyllaDB Cloud clusters easily using Terraform. Follow the instructions below to +set up the care-pet sample application in a ScyllaDB Cloud environment using Terraform.

      +

      You’ll set up Terraform to:

      +
        +
      1. Create a new ScyllaDB Cloud cluster (you need a ScyllaDB Cloud account)

      2. +
      3. Execute a CQL file that creates a new keyspace and tables for the care-pet project

      4. +
      +
      +

      Prerequisites

      + +
      +
      +

      Get started

      +
      +

      Clone the repository

      +

      Clone the repository if you haven’t already:

      +
      git clone https://github.com/scylladb/care-pet.git
      +
      +
      +
      +
      +

      Install CQLSH

      +

      Install the standalone CQLSH Python package:

      +
      pip install cqlsh
      +
      +
      +

      This package will be used to connect to ScyllaDB and create the initial schema.

      +
      +
      +

      Spin up a new ScyllaDB Cloud cluster

      +

      Go to the terraform directory and run terraform init

      +
      cd terraform/
      +terraform init
      +
      +
      +

      Apply the changes that are configured in the main.tf file:

      +
      terraform apply
      +
      +
      +

      You’ll be asked to provide your ScyllaDB Cloud API token (more info in docs):

      +
      var.scylla_api_token
      +  Your own ScyllaDB Cloud API token
      +
      +  Enter a value:
      +
      +
      +

      You’ll also be asked if you want to perform the actions configured in Terraform, just type yes:

      +
      Do you want to perform these actions?
      +  Terraform will perform the actions described above.
      +  Only 'yes' will be accepted to approve.
      +
      +  Enter a value: yes
      +
      +  scylladbcloud_cluster.care_pet: Creating...
      +
      +
      +

      Spinning up the cluster takes about ~10 minutes. While the process is underway, you can go to your +ScyllaDB Cloud dashboard and verify that the cluster is getting set up:

      +

      cluster setting up

      +

      After the process is completed, go to the “Connect” tab in in the cloud console +and connect to your newly created cluster with your favourite tool.

      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/design-and-data-model.html b/master/design-and-data-model.html new file mode 100644 index 00000000..fcbcb043 --- /dev/null +++ b/master/design-and-data-model.html @@ -0,0 +1,686 @@ + + + + + + + + + + + + + Design and Data Model | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Design and Data Model

      +

      You can learn more about Data Modeling in Scylla (and NoSQL) by taking +this course on Scylla +University. The main goal of data modeling in Scylla is to perform queries fast, +even if we sometimes have to duplicate data.

      +

      Let’s build our schema around the queries we are going to run against our domain +entities. When creating the data model, you need to consider both the conceptual +data model and the application workflow: which queries will be performed by +which users and how often.

      +

      To achieve that, we want:

      +
        +
      • Even data distribution

      • +
      • To minimize the number of partitions accessed in a read query.

      • +
      +

      On the other hand, our focus won’t be on avoiding data duplication or minimizing +the number of writes. You’re probably familiar with the steps defined here:

      +

      +
      +

      Conceptual Data Model

      +

      Starting with the conceptual data model, we need to identify the key entities +and the relationships between them. Our application has pets. Each dog can be +tracked by many followers (typically the owners). A follower can also track more +than one dog. Each dog can have a few sensors. Each sensor takes measurements:

      +

      +
      +
      +

      Application Workflow

      +

      Next, we move on to the Application Workflow. In this part, we identify the main +queries or what questions we will ask the database. This part is important in +Scylla, and other NoSQL databases and, as opposed to relational databases is +performed early on in the data modeling process. Remember that our data modeling +is built around the queries.

      +

      +
      +
      +

      Queries

      +

      Now we can detail the above queries in +CQL:

      +

      Q1: Find a Follower with a specific ID

      +
      SELECT * FROM owner WHERE owner_id = ?
      +
      +
      +

      Q2: Find the pets that the follower tracks

      +
      SELECT * FROM pet WHERE owner_id = ?
      +
      +
      +

      Q3: Find the sensors of a pet

      +
      SELECT * FROM sensor WHERE pet_id = ?
      +
      +
      +

      Q4: Find the measurements for a sensor in a date range

      +
      SELECT * FROM measurements WHERE sensor_id = ? AND ts <= ? and ts >= ?;
      +
      +
      +

      Q5: Find a daily summary of hour based aggregates

      +
      SELECT * FROM sensor_avg WHERE sensor_id = ? AND date = ? ORDER BY date ASC, hour ASC;
      +
      +
      +
      +
      +

      Logical Data Model

      +

      Using the outcomes of the application workflow and the conceptual data model, we +can now create the logical data model. At this stage, we determine how our +tables will look and which fields will be used as primary and clustering keys. +Selecting a primary key and clustering key is highly important, you can learn +more about it in +this lesson. +Remember that in Scylla, it’s better to duplicate data than to join, see more +about denormalization in +this lesson.

      +

      +
      +
      +

      Physical Data Model

      +

      In this part, we take the Logical Data Model above and add CQL data types. Make +sure you’re familiar with the ScyllaDB (and Cassandra for that matter) +data types +before proceeding.

      +

      Based on the high availability requirements, we will use a +replication factor +(RF) of three. The RF is defined when we create the +Keyspace, +as we will see later on. Choosing the compaction strategy is explained +here +and in this +University Lesson. For the tables sensor_avg and measurement, we will use the +Time Window Compaction Strategy (TWCS).

      +

      The reason is those tables contain time-series data. The “measurement” table +stores sensor measurements, and the “sensor_avg” stores aggregated hourly +averages. For such data, there is an optimized compaction strategy TWCS based on +the Size Tiered Compaction Strategy with the fair assumption that the data at +different time slots will never overlap. That isolates buckets compaction +in-between the time windows into independent units reducing overall compaction +write amplification. For the other tables, we will use the default +compaction strategy, +Size Tiered Compaction Strategy (STCS). +Remember that if you are using Scylla Enterprise, you should +probably be using Incremental Compaction Strategy (ICS) +as it offers better performance. We can now define the tables below, according +to the physical data model.

      +
      CREATE TABLE IF NOT EXISTS owner (
      +    owner_id UUID,
      +    address TEXT,
      +    name    TEXT,
      +    PRIMARY KEY (owner_id)
      +);
      +
      +CREATE TABLE IF NOT EXISTS pet (
      +    owner_id UUID,
      +    pet_id   UUID,
      +    chip_id  TEXT,
      +    species  TEXT,
      +    breed    TEXT,
      +    color    TEXT,
      +    gender   TEXT,
      +    age     INT,
      +    weight  FLOAT,
      +    address TEXT,
      +    name    TEXT,
      +    PRIMARY KEY (owner_id, pet_id)
      +);
      +
      +CREATE TABLE IF NOT EXISTS sensor (
      +    pet_id UUID,
      +    sensor_id UUID,
      +    type TEXT,
      +    PRIMARY KEY (pet_id, sensor_id)
      +);
      +
      +CREATE TABLE IF NOT EXISTS measurement (
      +    sensor_id UUID,
      +    ts       TIMESTAMP,
      +    value    FLOAT,
      +    PRIMARY KEY (sensor_id, ts)
      +) WITH compaction = { 'class' : 'TimeWindowCompactionStrategy' };
      +
      +CREATE TABLE IF NOT EXISTS sensor_avg (
      +    sensor_id UUID,
      +    date    DATE,
      +    hour    INT,
      +    value   FLOAT,
      +    PRIMARY KEY (sensor_id, date, hour)
      +) WITH compaction = { 'class' : 'TimeWindowCompactionStrategy' };
      +
      +
      +

      Some more advanced topics not covered in this guide are +Collections, +User-DefinedTypes +(UDT), expiring data with time to live (TTL), +and Counters.

      +

      To summarize, when data modeling with Scylla, we have to know our data, think +about our queries, pay attention to the primary key and clustering key +selection, and not be afraid to duplicate data.

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/genindex.html b/master/genindex.html new file mode 100644 index 00000000..d50e4c43 --- /dev/null +++ b/master/genindex.html @@ -0,0 +1,499 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + + + + + +
      + + + + + +
      + + +
      + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/getting-started.html b/master/getting-started.html new file mode 100644 index 00000000..78891ba6 --- /dev/null +++ b/master/getting-started.html @@ -0,0 +1,659 @@ + + + + + + + + + + + + + Getting Started with CarePet: A sample IoT App | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + +
      + +
      + +
      +

      Getting Started with CarePet: A sample IoT App

      +
      +

      Introduction

      +

      This guide will show you how to create an IoT app from scratch and configure it +to use Scylla as the backend datastore. It’ll walk you through all the stages +of the development process, from gathering requirements to building and running +the application.

      +

      As an example, you will use an application called CarePet. CarePet allows pet +owners to track their pets’ health by monitoring their key health parameters, +such as temperature or pulse. The application consists of three parts:

      +
        +
      • A pet collar with sensors that collects pet health data and sends the data to the datastore.

      • +
      • A web app for reading the data and analyzing the pets’ health.

      • +
      • A database migration module.

      • +
      +

      You can use this example with minimal changes for any IoT application.

      +
      +
      +

      Architecture

      +
        +
      • migrate - Creates the CarePet keyspace and tables.

      • +
      • sensor - Generates pet health data and pushes it into storage.

      • +
      • server - REST API service for tracking the pets’ health state.

      • +
      +

      Build your first ScyllaDB Powered App - Raouf

      +
      +
      +

      Requirements

      +
      +

      Prerequisites for Deploying the Application

      +

      The example application uses Docker to run a three-node ScyllaDB cluster. You can also use Scylla Cloud as your database. +Claim your free Scylla Cloud account here.

      +
      +
      +

      Use Case Requirements

      +

      Each pet collar has sensors that report four different measurements: +temperature, pulse, location, and respiration.

      +

      The collar reads the measurements from the sensors once per second +and sends the data directly to the app.

      +
      +
      +

      Performance Requirements

      +

      The application has two performance-related parts: sensors that write to +the database (throughput sensitive) and a backend dashboard that reads from +the database (latency sensitive).

      +
        +
      • This example assumes 99% writes (sensors) and 1% reads (backend dashboard).

      • +
      • SLA:

        +
          +
        • Writes: throughput of 100K operations per second.

        • +
        • Reads: latency of up to 10 milliseconds for the +99th percentile.

        • +
        +
      • +
      • The application requires high availability and fault tolerance. Even if a +ScyllaDB node goes down or becomes unavailable, the cluster is expected to +remain available and continue to provide service. You can learn more about +Scylla high availability in this lesson.

      • +
      +
      +
      +
      +

      Deploying the Application in ScyllaDB Cloud

      +

      Using the ScyllaDB Cloud Terraform provider, you can easily spin up new ScyllaDB Cloud clusters. Complete this tutorial quicker by creating a new t3.micro cluster (the smallest instance) in ScyllaDB Cloud. Go to Deploy in ScyllaDB Cloud with Terraform for instructions.

      +
      +
      +

      Deploying the Application Locally

      +
        +
      1. Check out the care-pet repository from GitHub and go to the directory of +the language you want to use (Go, Java, etc.):

        +
        git clone git@github.com:scylladb/care-pet.git
        +cd care-pet/go
        +
        +
        +
      2. +
      3. Create a local ScyllaDB cluster consisting of three nodes:

        +
        docker-compose up -d
        +
        +
        +

        Docker-compose will spin up a ScyllaDB cluster consisting of three nodes: +carepet-scylla1, carepet-scylla2 and carepet-scylla3. The process will +take about two minutes.

        +
      4. +
      5. Check the status of the cluster:

        +
        docker exec -it carepet-scylla1 nodetool status
        +
        +
        +
      6. +
      7. Continue by following the instructions for the programming language you’re using. See Build the Application with Your Programming Language.

      8. +
      +
      +
      +

      Build the Application with Your Programming Language

      + +
      +
      +

      Additional Resources

      + +

      Future Work

      +
        +
      • Add Sizing

      • +
      • Add Benchmarking

      • +
      • Add Python implementation

      • +
      • In a real-world application, it would be better to aggregate data in an internal buffer and send it once a day to the application gateway in a batch, implying techniques such as delta encoding. It could also aggregate data at a lower resolution and take measurements less frequently. The collar could notify the pet’s owner about suspicious health parameters directly or via the application.

      • +
      • Add location tracking info to send alerts when the pet enters/leaves safe zones using known WiFi networks.

      • +
      • Use the measurements to present to the pet owner health alerts, vital signs, sleeping levels, activity levels, and calories burned.

      • +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/index.html b/master/index.html new file mode 100644 index 00000000..aec951a0 --- /dev/null +++ b/master/index.html @@ -0,0 +1,618 @@ + + + + + + + + + + + + + Scylla Care-Pet Example | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/objects.inv b/master/objects.inv new file mode 100644 index 00000000..2ad88597 Binary files /dev/null and b/master/objects.inv differ diff --git a/master/search.html b/master/search.html new file mode 100644 index 00000000..99db6ba6 --- /dev/null +++ b/master/search.html @@ -0,0 +1,502 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + + + + + + + +
      + + + + + +
      + + +
      + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/master/searchindex.js b/master/searchindex.js new file mode 100644 index 00000000..b19ce308 --- /dev/null +++ b/master/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["build-with-go", "build-with-java", "build-with-javascript", "build-with-php", "build-with-python", "build-with-rust", "deploy-in-cloud", "design-and-data-model", "getting-started", "index"], "filenames": ["build-with-go.md", "build-with-java.md", "build-with-javascript.md", "build-with-php.md", "build-with-python.md", "build-with-rust.md", "deploy-in-cloud.md", "design-and-data-model.md", "getting-started.md", "index.rst"], "titles": ["Build an IoT App with Go", "Build an IoT App with Java", "Build an IoT App with JavaScript", "Care Pet ScyllaDB PHP IoT example", "Build an IoT App with Python", "Build an IoT App with Rust", "Deploy in ScyllaDB Cloud with Terraform", "Design and Data Model", "Getting Started with CarePet: A sample IoT App", "Scylla Care-Pet Example"], "terms": {"In": [0, 1, 2, 4, 7, 8], "thi": [0, 1, 2, 3, 5, 6, 7, 8, 9], "section": [0, 1, 2, 4, 5], "we": [0, 1, 2, 3, 5, 7], "walk": [0, 1, 2, 4, 5, 8, 9], "you": [0, 1, 2, 3, 5, 6, 7, 8, 9], "through": [0, 1, 2, 3, 4, 5, 8, 9], "carepet": [0, 1, 2, 3, 4, 5], "command": [0, 1, 2, 4, 5], "explain": [0, 1, 2, 4, 5, 7, 8], "code": [0, 1, 4, 5], "behind": [0, 1, 2], "them": [0, 1, 2, 4, 7], "As": [0, 4, 5, 8], "get": [0, 1, 2, 4, 5, 9], "start": [0, 1, 5, 7, 9], "project": [0, 1, 2, 3, 4, 5, 6, 9], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "structur": [0, 1, 4, 5], "follow": [0, 1, 2, 3, 4, 5, 6, 7, 8], "cmd": [0, 2], "creat": [0, 1, 2, 3, 5, 6, 7, 8, 9], "keyspac": [0, 1, 2, 4, 5, 6, 7, 8], "tabl": [0, 1, 2, 3, 4, 5, 6, 7, 8], "collar": [0, 1, 2, 4, 5, 8], "simul": [0, 1, 2, 4, 5], "pet": [0, 1, 2, 4, 5, 6, 7, 8, 9], "": [0, 1, 2, 3, 4, 5, 7, 8], "gener": [0, 1, 2, 3, 5, 8], "health": [0, 1, 2, 3, 5, 8], "data": [0, 1, 2, 5, 8, 9], "push": [0, 1, 2, 3, 4, 5, 8], "storag": [0, 1, 2, 3, 4, 5, 8], "rest": [0, 1, 2, 3, 5, 8], "api": [0, 1, 2, 3, 6, 8], "servic": [0, 1, 2, 3, 4, 5, 8, 9], "track": [0, 1, 2, 3, 5, 7, 8], "state": [0, 1, 2, 3, 4, 5, 8], "The": [0, 1, 2, 3, 4, 5, 7, 8, 9], "us": [0, 1, 5, 6, 7, 9], "line": [0, 1, 4], "25": 0, "27": [0, 1], "file": [0, 1, 3, 5, 6], "call": [0, 1, 2, 5, 8], "createkeyspac": [0, 1], "migratekeyspac": 0, "printkeyspacemetadata": 0, "function": [0, 1, 2, 3, 5], "func": 0, "main": [0, 1, 2, 5, 6, 7], "new": [0, 1, 2, 3, 4, 5, 8, 9], "session": [0, 1, 2, 3, 5], "execut": [0, 1, 2, 3, 5, 6], "cql": [0, 1, 2, 3, 5, 6, 7], "queri": [0, 1, 2, 3, 5, 8, 9], "store": [0, 1, 3, 7], "db": [0, 2, 5], "IF": [0, 1, 2, 3, 5, 7], "NOT": [0, 1, 2, 3, 5, 7], "exist": [0, 1, 2, 3, 5, 7], "WITH": [0, 1, 2, 3, 4, 5, 7], "replic": [0, 1, 2, 3, 5, 7], "class": [0, 1, 2, 3, 4, 5, 7], "networktopologystrategi": [0, 1, 2, 3, 5], "replication_factor": [0, 1, 2, 3, 5], "3": [0, 1, 2, 3, 4, 5], "AND": [0, 1, 2, 4, 5, 7], "durable_writ": [0, 1], "true": [0, 1, 2, 3, 4, 5], "se": 0, "err": [0, 5], "config": [0, 1, 2, 3, 5], "nil": 0, "log": [0, 1, 2, 5], "fatalln": 0, "defer": 0, "close": [0, 2, 3], "check": [0, 1, 2, 5, 8], "error": [0, 3, 5], "keyspacecql": 0, "exec": [0, 1, 2, 3, 4, 5, 8], "ensur": 0, "open": [0, 1, 2, 4], "locat": [0, 1, 2, 8], "care": [0, 1, 2, 4, 6, 8, 9], "ddl": [0, 1], "owner": [0, 1, 2, 3, 4, 5, 7, 8], "measur": [0, 1, 2, 4, 5, 7, 8], "sensor_avg": [0, 1, 2, 4, 7], "om": 0, "context": 0, "background": 0, "name": [0, 1, 2, 3, 4, 5, 7], "suggest": [0, 4], "print": [0, 1], "metadata": [0, 1, 2], "relat": [0, 1, 3, 7, 8], "confirm": [0, 1], "were": 0, "properli": [0, 1, 4], "activ": [0, 1, 2, 3, 4, 5, 8], "struct": 0, "its": 0, "defin": [0, 1, 2, 5, 7], "along": [0, 5], "sensortyp": [0, 1], "save": [0, 1, 2, 4, 5], "databas": [0, 1, 2, 5, 7, 8, 9], "newpet": 0, "println": 0, "p": [0, 2, 3, 5], "ownerid": [0, 3], "petid": [0, 3], "run": [0, 1, 4, 5, 6, 7, 8], "allow": [0, 1, 2, 3, 5, 8], "user": [0, 2, 5, 7, 8], "via": [0, 1, 2, 5, 8], "http": [0, 1, 2, 3, 4, 5, 6], "exampl": [0, 1, 2, 4, 5, 8, 9], "curl": [0, 1, 2, 4, 5], "127": [0, 1, 2, 4, 5], "0": [0, 1, 2, 3, 4, 5], "1": [0, 1, 2, 3, 4, 5, 8], "8000": [0, 1, 2, 3, 4, 5], "id": [0, 1, 2, 3, 4, 5, 7], "expect": [0, 1, 2, 5, 8], "respons": [0, 1, 5], "address": [0, 1, 2, 4, 5, 7], "home": [0, 1, 2, 4, 5], "ag": [0, 1, 2, 4, 5, 7], "57": [0, 1, 2], "tlmodylu": [0, 1, 2], "owner_id": [0, 1, 2, 3, 4, 5, 7], "a05fd0df": [0, 1, 2], "0f97": [0, 1, 2], "4eec": [0, 1, 2], "a211": [0, 1, 2], "cad28a6e5360": [0, 1, 2], "pet_id": [0, 1, 2, 3, 4, 5, 7], "a52adc4": [0, 1, 2], "7cf4": [0, 1, 2], "47ca": [0, 1, 2], "b561": [0, 1, 2], "3ceec9382917": [0, 1, 2], "weight": [0, 1, 2, 4, 5, 7], "5": [0, 1, 2, 3, 5], "let": [0, 1, 2, 3, 5, 7], "first": [0, 1, 3, 4], "discuss": 0, "from": [0, 2, 3, 4, 7, 8, 9], "23": 0, "28": 0, "oper": [0, 8], "newcarepetapi": 0, "spec": [0, 2, 3], "restapi": 0, "newserv": 0, "shutdown": 0, "configur": [0, 2, 5, 6, 8, 9], "configureapi": 0, "object": [0, 1, 5], "repres": 0, "list": [0, 1, 2, 3, 5], "swagger": 0, "tool": [0, 6], "those": [0, 7], "ar": [0, 1, 2, 3, 5, 6, 7], "pass": [0, 1], "method": [0, 1, 2, 5], "handler": [0, 2, 5], "One": 0, "findownerbyid": 0, "gocqlx": 0, "findownerbyidhandlerfunc": 0, "return": [0, 1, 2, 3, 4, 5], "param": [0, 2, 5], "findownerbyidparam": 0, "middlewar": 0, "respond": 0, "var": [0, 3, 6], "model": [0, 1, 2, 8, 9], "tableown": 0, "getqueri": 0, "bind": [0, 1], "string": [0, 1, 3], "getreleas": 0, "gocql": [0, 2], "errnotfound": 0, "findownerbyiddefault": 0, "statu": [0, 2, 3, 4, 5, 8], "404": [0, 2], "newfindownerbyiddefault": 0, "statusnotfound": 0, "els": 0, "find": [0, 3, 7], "500": 0, "statusinternalservererror": 0, "200": 0, "inform": [0, 1, 2, 8, 9], "findownerbyidok": 0, "payload": 0, "conv": 0, "uuid": [0, 1, 2, 3, 4, 5, 7], "strfmt": 0, "result": [0, 1, 2, 5], "throw": 0, "found": [0, 2, 5], "32": [0, 3], "scylladb": [0, 1, 5, 7, 9], "driver": [0, 1, 2, 3, 4, 5], "github": [0, 1, 2, 3, 4, 5, 6, 8], "univers": [0, 1, 2, 4, 5, 7, 8], "scylla": [0, 1, 3, 5, 7, 8, 9], "document": [0, 1, 3, 4, 5, 8], "page": [0, 4, 5], "com": [1, 2, 3, 4, 6, 8], "web": [1, 2, 5, 8], "bin": [1, 4, 5], "sh": 1, "host": [1, 2, 3, 5], "node1": [1, 2, 4, 5], "datacent": [1, 3], "datacenter1": [1, 2, 3], "createschema": 1, "printmetadata": 1, "public": [1, 3], "static": 1, "void": [1, 3], "arg": [1, 3, 4], "final": [1, 2, 3, 4, 5], "pars": [1, 2], "client": [1, 2], "break": [1, 2], "down": [1, 2, 3, 8], "argument": [1, 2, 4, 5], "our": [1, 3, 7], "case": [1, 3], "ip": [1, 2, 4, 5], "one": [1, 4, 7], "node": [1, 2, 4, 5, 8], "default": [1, 3, 5, 7], "could": [1, 8], "differ": [1, 2, 4, 5, 7, 8], "cloud": [1, 3, 9], "also": [1, 6, 7, 8], "accept": [1, 2, 6], "usernam": [1, 2, 3, 5], "password": [1, 2, 3, 5], "requir": [1, 2, 4, 7], "cqlsession": 1, "info": [1, 2, 3, 4, 5, 6, 8], "try": 1, "connect": [1, 2, 3, 5, 6, 9], "getresourc": 1, "abov": [1, 2, 5, 6, 7], "strategi": [1, 2, 5, 7], "factor": [1, 2, 3, 5, 7], "see": [1, 2, 3, 4, 7, 8], "more": [1, 2, 3, 5, 6, 7, 8, 9], "about": [1, 2, 4, 5, 6, 7, 8, 9], "split": 1, "can": [1, 2, 3, 4, 5, 6, 7, 8], "docker": [1, 2, 3, 5, 8], "scylla1": [1, 2, 3, 4, 5, 8], "cqlsh": [1, 2, 3, 4, 5], "describ": [1, 2, 4, 5, 6], "should": [1, 2, 3, 5, 7], "chip_id": [1, 2, 5, 7], "text": [1, 2, 4, 5, 7], "speci": [1, 2, 5, 7], "breed": [1, 2, 5, 7], "color": [1, 2, 5, 7], "gender": [1, 2, 5, 7], "int": [1, 2, 3, 4, 5, 7], "float": [1, 2, 4, 5, 7], "primari": [1, 2, 4, 5, 7, 9], "kei": [1, 2, 3, 4, 5, 7, 8, 9], "cluster": [1, 2, 3, 4, 5, 7, 8, 9], "order": [1, 2, 4, 5, 7], "BY": [1, 2, 4, 5, 7], "asc": [1, 2, 4, 5, 7], "bloom_filter_fp_ch": [1, 2, 4, 5], "01": [1, 2, 3, 4, 5], "cach": [1, 2, 4, 5], "all": [1, 2, 3, 4, 5, 8], "rows_per_partit": [1, 2, 4, 5], "comment": [1, 2, 4, 5], "compact": [1, 2, 4, 5, 7], "sizetieredcompactionstrategi": [1, 2, 4, 5], "compress": [1, 2, 4, 5], "sstable_compress": [1, 2, 4, 5], "org": [1, 2, 4, 5], "apach": [1, 2, 4, 5], "cassandra": [1, 2, 3, 4, 5, 7], "io": [1, 2, 4, 5], "lz4compressor": [1, 2, 4, 5], "crc_check_chanc": [1, 2, 4, 5], "dclocal_read_repair_ch": [1, 2, 4, 5], "default_time_to_l": [1, 2, 4, 5], "gc_grace_second": [1, 2, 4, 5], "864000": [1, 2, 4, 5], "max_index_interv": [1, 2, 4, 5], "2048": [1, 2, 4, 5], "memtable_flush_period_in_m": [1, 2, 4, 5], "min_index_interv": [1, 2, 4, 5], "128": [1, 2, 4, 5], "read_repair_ch": [1, 2, 4, 5], "speculative_retri": [1, 2, 4, 5], "99": [1, 2, 4, 5, 8], "0percentil": [1, 2, 4, 5], "mvn": 1, "packag": [1, 2, 6], "inspect": [1, 2, 4, 5], "f": [1, 2, 3, 4, 5], "rang": [1, 2, 3, 4, 5, 7], "networkset": [1, 2, 3, 4, 5], "network": [1, 2, 3, 4, 5, 8], "ipaddress": [1, 2, 3, 4, 5], "end": [1, 2, 3, 4, 5, 9], "pt1m": 1, "buffer": [1, 2, 4, 5, 8], "interv": [1, 2, 4, 5], "sensorconfig": 1, "instanc": [1, 2, 3, 8], "like": [1, 2, 3, 4], "constructor": 1, "random": [1, 2, 4, 5], "attribut": 1, "getownerid": 1, "valu": [1, 2, 3, 4, 5, 6, 7], "length": [1, 2], "getpetid": 1, "datbas": [1, 5], "privat": [1, 3], "mapper": 1, "m": [1, 5], "builder": [1, 3], "preparedstat": 1, "batchstatementbuild": 1, "multipl": [1, 4], "same": [1, 4], "time": [1, 4, 5, 7, 9], "doc": [1, 3, 5, 6], "stabl": 1, "manual": 1, "core": [1, 3], "statement": 1, "prepar": [1, 2, 3], "detail": [1, 7], "insert": [1, 2, 4, 5], "INTO": [1, 3], "sensor_id": [1, 2, 4, 5, 7], "t": [1, 2, 3, 4, 5, 6, 7], "batchtyp": 1, "unlog": 1, "arraylist": 1, "instant": [1, 5], "prev": 1, "now": [1, 2, 4, 5, 7], "while": [1, 2, 5, 6], "durat": [1, 5], "between": [1, 2, 5, 7], "compareto": 1, "bufferinterv": [1, 2], "sleep": [1, 5, 8], "readsensordata": [1, 2], "add": [1, 2, 7, 8, 9], "tostr": 1, "plusmilli": 1, "tomilli": 1, "simplifi": 1, "batch": [1, 2, 3, 4, 5, 8], "standard": 1, "best": 1, "practic": 1, "up": [1, 2, 3, 5, 8, 9], "partit": [1, 7], "www": [1, 3], "2019": 1, "03": 1, "applic": [1, 4, 6], "addstat": 1, "getsensorid": 1, "gett": 1, "getvalu": 1, "clearstat": 1, "clear": 1, "control": 1, "modelcontrol": 1, "implement": [1, 8], "access": [1, 2, 7], "aggreg": [1, 2, 7, 8], "saveaggreg": 1, "monoton": 1, "sequenti": 1, "sensorid": 1, "prevavgs": 1, "locald": 1, "dai": [1, 2, 8], "localdatetim": 1, "current": 1, "hour": [1, 7], "boolean": 1, "samed": 1, "getdayofyear": 1, "gethour": 1, "size": [1, 7, 8], "sensoravg": 1, "npm": 2, "dev": 2, "purpos": 2, "backend": [2, 8, 9], "instal": 2, "schema": [2, 6, 7, 9], "x": [2, 3], "orm": 2, "prerequisit": [2, 3], "nodej": 2, "test": [2, 5], "v17": 2, "v8": 2, "compos": [2, 3, 4, 5, 8], "clone": [2, 5, 8], "repositori": [2, 3, 8], "chang": [2, 3, 4, 6, 8], "directori": [2, 4, 6, 8], "git": [2, 4, 6, 8], "cd": [2, 4, 6, 8], "make": [2, 3, 4, 7, 9], "sure": [2, 4, 7], "depend": 2, "To": [2, 3, 4, 5, 7], "consist": [2, 3, 5, 8], "three": [2, 3, 4, 7, 8], "help": [2, 3], "d": [2, 3, 4, 5, 8], "spin": [2, 3, 4, 5, 8, 9], "scylla2": [2, 3, 4, 5, 8], "scylla3": [2, 3, 4, 5, 8], "nodetool": [2, 5, 8], "onc": [2, 5, 8], "un": [2, 3, 5], "normal": [2, 3, 5], "below": [2, 5, 6, 7], "If": [2, 3, 5], "replac": 2, "provid": [2, 4, 6, 8], "2020": 2, "08": [2, 4], "06": [2, 3], "16": 2, "43": 2, "bootstrap": [2, 5], "13": [2, 4], "durablewrit": 2, "strategyclass": 2, "strategyopt": 2, "map": [2, 5], "gocqlx_migr": 2, "0xc00016ca80": 2, "0xc00016cbb0": 2, "0xc00016cce0": 2, "0xc00016ce10": 2, "0xc00016cf40": 2, "0xc00016d070": 2, "type": [2, 3, 4, 5, 6, 7], "view": 2, "rm": 2, "entrypoint": [2, 3, 4], "u": 2, "note": 2, "system_schema": [2, 4], "system_auth": [2, 4], "system": [2, 4], "system_distribut": [2, 4], "system_trac": [2, 4], "exit": [2, 4], "need": [2, 3, 4, 5, 6, 7], "create_keyspac": [2, 3, 5], "async": [2, 5], "const": [2, 3], "option": [2, 4], "opt": 2, "await": [2, 5], "getclient": 2, "debug": [2, 5], "take": [2, 5, 6, 7, 8], "paramet": [2, 4, 5, 8], "src": [2, 4, 5], "contactpoint": 2, "authprovid": 2, "auth": 2, "plaintextauthprovid": 2, "localdatacent": 2, "loop": [2, 5], "With": 2, "period": [2, 5], "1m": [2, 5], "44": 2, "33": [2, 3], "welcom": [2, 4, 5], "9b20764b": 2, "f947": 2, "45bb": 2, "a020": 2, "bf6d02cc2224": 2, "f3a836c7": 2, "ec64": 2, "44c3": 2, "b66f": 2, "0abe9ad2befd": 2, "48212af8": 2, "afff": 2, "43ea": 2, "9240": 2, "c0e5458d82c1": 2, "l": [2, 3, 4, 5], "51": 2, "360596": 2, "06t16": 2, "02": 2, "00": 2, "2ff06ffb": 2, "ecad": 2, "4c55": 2, "be78": 2, "0a3d413231d9": 2, "r": [2, 3, 4, 5], "36": [2, 3, 4], "821588e0": 2, "840d": 2, "48c6": 2, "b9c9": 2, "7d1045e0f38c": 2, "26": 2, "380281": 2, "when": [2, 4, 7, 8], "authent": 2, "enabl": 2, "two": [2, 4, 5, 8], "cli": [2, 3], "parsedur": 2, "getclientwithkeyspac": 2, "randomdata": 2, "savedata": 2, "runsensordata": 2, "just": [2, 6], "insertqueri": 2, "everi": [2, 4, 5], "buffer_interv": [2, 5], "last": [2, 5], "moment": 2, "diff": 2, "delai": 2, "toisostr": 2, "valueof": 2, "45": 2, "58": 2, "serv": [2, 3], "mount": [2, 5], "rout": [2, 5], "json": [2, 5], "stringifi": 2, "asynchandl": 2, "avg": [2, 5], "listen": 2, "port": [2, 3, 4], "termin": [2, 4, 5], "send": [2, 8], "request": [2, 5], "v": [2, 5], "agent": 2, "7": [2, 3], "71": 2, "mark": 2, "bundl": 2, "support": 2, "multius": 2, "Not": 2, "content": 2, "date": [2, 7], "thu": [2, 3], "aug": 2, "14": [2, 4], "47": 2, "41": 2, "gmt": 2, "messag": [2, 4], "path": [2, 3, 4], "wa": [2, 5], "indic": [2, 3], "behavior": 2, "read": [2, 7, 8, 9], "previous": 2, "For": [2, 3, 4, 5, 7], "gmwjgsap": 2, "each": [2, 3, 5, 7, 8], "cef72f58": 2, "fc78": 2, "4cae": 2, "92ae": 2, "fb3c3eed35c4": 2, "5a9da084": 2, "ea49": 2, "4ab1": 2, "b2f8": 2, "d3e3d9715e7d": 2, "5c70cd8a": 2, "d9a6": 2, "416f": 2, "afd6": 2, "c99f90578d99": 2, "fbefa67a": 2, "ceb1": 2, "4dcc": 2, "bbf1": 2, "c90d71176857": 2, "review": 2, "specif": [2, 5, 7], "2006": 2, "02t15": 2, "04": 2, "05z07": 2, "06t00": 2, "00z": 2, "06t23": 2, "59": [2, 3], "59z": 2, "737432": 2, "77": 2, "88015": 2, "daili": [2, 7], "averag": [2, 7], "per": [2, 8], "42": 2, "55736": 2, "third": [2, 3], "parti": [2, 3], "demonstr": 3, "here": [3, 7, 8], "possibl": 3, "integr": [3, 9], "version": 3, "datastax": 3, "8": 3, "2": [3, 4], "commun": 3, "build": [3, 7, 9], "instruct": [3, 6, 8], "strongli": 3, "recommend": 3, "go": [3, 5, 6, 7, 8, 9], "sinc": 3, "still": [3, 4], "being": 3, "maintain": 3, "develop": [3, 8], "itself": 3, "guid": [3, 7, 8, 9], "exercis": 3, "part": [3, 7, 8], "descript": 3, "migrat": [3, 4, 8], "local": [3, 4, 5], "which": [3, 6, 7], "want": [3, 5, 6, 7, 8], "your": [3, 4, 5, 6], "someth": 3, "imag": 3, "4e351dfe3987": 3, "minut": [3, 5, 6, 8], "ago": 3, "22": 3, "tcp": 3, "7000": 3, "7001": 3, "7199": 3, "9042": 3, "9160": 3, "9180": 3, "10000": 3, "9e7e4d3992df": 3, "7e2b1b94389b": 3, "have": [3, 4, 5, 7], "ani": [3, 4, 8], "regard": 3, "prematur": 3, "restart": 3, "wait": [3, 4, 5], "until": 3, "establish": 3, "everyth": 3, "own": [3, 6], "research": 3, "These": 3, "enter": [3, 6, 8], "remot": 3, "copi": [3, 4], "env": [3, 4], "secret": 3, "cp": 3, "By": 3, "readi": 3, "db_keyspac": 3, "db_node": 3, "localhost": 3, "db_usernam": 3, "db_password": 3, "db_port": 3, "product": 3, "aws_sa_east_1": 3, "c106d1ac5f3117a20bf0": 3, "p50bonfq8cuxwx": 3, "rememb": [3, 7], "10": [3, 4, 6, 8], "nativ": 3, "protocol": 3, "v4": 3, "Then": 3, "insid": 3, "fetch": [3, 4], "create_owner_t": 3, "create_pets_t": 3, "4": [3, 5], "create_sensors_t": 3, "create_measurements_t": 3, "6": [3, 4], "create_sensor_avg_t": 3, "done": [3, 4], "jan": 3, "17": [3, 4], "2023": [3, 4], "593dec12": 3, "6bea": 3, "3c93": 3, "8f49": 3, "26d8b6d589b1": 3, "14d9f304": 3, "5600": 3, "34af": 3, "8622": 3, "3d4505d617d7": 3, "869bd01e": 3, "e0ba": 3, "364f": 3, "bbfb": 3, "8c7c496a3318": 3, "c86f63b0": 3, "1439": 3, "3404": 3, "8750": 3, "b71b90a685cb": 3, "e0550426": 3, "8832": 3, "3d17": 3, "9025": 3, "77726b3009c5": 3, "bf960c81": 3, "8e0f": 3, "3012": 3, "b50d": 3, "18596b50db18": 3, "933245de": 3, "812e": 3, "34e4": 3, "8d50": 3, "2ab072726217": 3, "319ec566": 3, "d6b0": 3, "3868": 3, "ac5": 3, "76253ee7c236": 3, "simulatecommand": 3, "extend": 3, "abstractcommand": 3, "__construct": 3, "readonli": 3, "ownerrepositori": 3, "petrepositori": 3, "sensorrepositori": 3, "amount_bas": 3, "50000": 3, "__invok": 3, "arrai": 3, "foreach": 3, "self": 3, "ownerdto": 3, "petsdto": 3, "generatefakedata": 3, "sprintf": 3, "petdto": 3, "sensorfactori": 3, "makemani": 3, "handlesensor": 3, "success": 3, "ownerfactori": 3, "petfactori": 3, "closur": 3, "sensordto": 3, "futurerow": 3, "simplestat": 3, "connector": 3, "connectionbuild": 3, "base_timeout": 3, "withcontactpoint": 3, "withdefaultconsist": 3, "consistency_level": 3, "withport": 3, "empti": 3, "withcredenti": 3, "setkeyspac": 3, "executeasync": 3, "app": [3, 9], "entiti": [3, 7], "abstractdto": 3, "row": [3, 5], "abstract": 3, "abstractrepositori": 3, "primarykei": 3, "getbyid": 3, "select": [3, 5, 7, 9], "where": [3, 5, 7], "dto": 3, "array_kei": 3, "todatabas": 3, "datavalu": 3, "array_valu": 3, "is_str": 3, "in_arrai": 3, "addslash": 3, "implod": 3, "leav": [3, 8], "join": [3, 5, 7], "move": [3, 7], "load": 3, "token": [3, 6], "rack": 3, "212": 3, "kb": 3, "256": 3, "f6121e15": 3, "48df": 3, "4b31": 3, "b725": 3, "3ad2795b8b94": 3, "rack1": 3, "mb": 3, "871795f3": 3, "67d2": 3, "47ba": 3, "83ef": 3, "15714b89c02a": 3, "cbe74a63": 3, "2cf4": 3, "41c2": 3, "bf7f": 3, "c831c0d2689f": 3, "bash": 3, "_____": 3, "_": [3, 5], "____": 3, "__": 3, "___": 3, "avail": [3, 4, 7, 8], "root": [3, 4], "mean": [3, 6], "7e2b1b94389b36c494093db8e119c2b8c5167339f20e03d9bfa070e8e46f8430": 3, "05t17": 3, "038609825z": 3, "py": [3, 4], "smp": [3, 4], "paus": 3, "fals": 3, "sensor": [4, 7, 8], "virtual": 4, "environ": [4, 6, 9], "virtualenv": 4, "sourc": 4, "pip": [4, 6], "txt": 4, "c87128b7d0ca4a31a84da78875c8b4181283c34783b6b0a78bffbacbbe45fcc2": 4, "08t21": 4, "212585687z": 4, "within": 4, "know": [4, 7], "how": [4, 7, 8], "refer": 4, "later": [4, 7], "so": 4, "easier": 4, "variabl": 4, "script": 4, "h": 4, "system_distributed_everywher": 4, "At": [4, 7], "point": 4, "correct": 4, "do": [4, 6], "separ": 4, "becaus": 4, "process": [4, 6, 7, 8], "indefinit": 4, "re": [4, 7, 8], "1cfbc0e5": 4, "6b05": 4, "476d": 4, "b170": 4, "2660cf40c02a": 4, "1a0800e": 4, "7643": 4, "4794": 4, "af7b": 4, "2ecaaf7078fc": 4, "b6155934": 4, "bd4e": 4, "47de": 4, "8649": 4, "1fad447aa036": 4, "d2c62c4d": 4, "9621": 4, "469d": 4, "b62c": 4, "41ef2271fca7": 4, "100": 4, "55118431400851": 4, "126374": 4, "37": 4, "486651732296835": 4, "126516": 4, "come": 4, "other": [4, 7, 8], "second": [4, 8], "ten": 4, "whenev": 4, "actual": 4, "instert": 4, "modifi": 4, "frequenc": 4, "30": 4, "parallel": 4, "wish": 4, "server": [4, 8], "free": [4, 8], "696274": 4, "startup": 4, "complet": [4, 6, 8, 9], "uvicorn": 4, "press": 4, "ctrl": 4, "c": 4, "quit": 4, "browser": 4, "work": [4, 8], "next": [4, 7], "endpoint": 4, "field": [4, 7], "either": 4, "url": [4, 5], "begin": 4, "output": 4, "what": [4, 7], "right": 4, "after": [4, 6, 9], "A": [4, 7], "look": [4, 5, 7], "past": 4, "4f42fb80": 4, "c209": 4, "4d19": 4, "8c43": 4, "daf554f1be23": 4, "vito": 4, "russel": 4, "44f1624e": 4, "07c2": 4, "4971": 4, "85a5": 4, "85b9ad1ff142": 4, "20": 4, "duke": 4, "41481876373291": 4, "4bb1d214": 4, "712b": 4, "453b": 4, "b53a": 4, "ac5d4df4a1f8": 4, "e81915d6": 4, "1155": 4, "45e4": 4, "9174": 4, "c58e4cb8cecf": 4, "contain": [5, 7], "cargo": 5, "fn": 5, "care_pet": [5, 6], "init": [5, 6], "from_arg": 5, "sess": 5, "new_sess": 5, "db_config": 5, "ok": 5, "sessionbuild": 5, "crete": 5, "mod": 5, "pub": 5, "known_nod": 5, "connection_timeout": 5, "timeout": 5, "unwrap_or_default": 5, "map_err": 5, "pleas": 5, "tokio": 5, "new_session_with_keyspac": 5, "random_data": 5, "save_data": 5, "run_sensor_data": 5, "use_keyspac": 5, "insert_queri": 5, "macro": 5, "cfg": 5, "vec": 5, "mut": 5, "elaps": 5, "read_sensor_data": 5, "as_str": 5, "format_rfc3339": 5, "from_nano": 5, "as_nano": 5, "u64": 5, "iter": 5, "fold": 5, "append_stat": 5, "built": [5, 7], "rocket": 5, "verbos": 5, "find_sensor_data_by_sensor_id_and_time_rang": 5, "find_owner_by_id": 5, "find_pets_by_owner_id": 5, "find_sensors_by_pet_id": 5, "find_sensor_avg_by_sensor_id_and_dai": 5, "manag": 5, "launch": 5, "folder": 5, "mesur": 5, "uuidparam": 5, "datetimeparam": 5, "f32": 5, "jsonerror": 5, "format": 5, "field_nam": 5, "json_err": 5, "internalservererror": 5, "into_typ": 5, "collect": [5, 7, 8], "trigger": 5, "out": [5, 8], "don": 5, "receiv": 5, "similar": 5, "5b5a7b4d": 5, "a2c0": 5, "48b0": 5, "91e1": 5, "de6a5b37c923": 5, "sedtdkaa": 5, "9e9facb9": 5, "3bd8": 5, "4451": 5, "b179": 5, "8c951cdf0999": 5, "null": 5, "dog": [5, 7], "golden": 5, "black": 5, "9": 5, "523097": 5, "awesom": 5, "doggo": 5, "7a8b3831": 5, "0512": 5, "4501": 5, "90f2": 5, "700c7133aeed": 5, "81250bab": 5, "cf1c": 5, "4c7a": 5, "84f1": 5, "b291a0f325ef": 5, "a22a2fdb": 5, "4aad": 5, "4abe": 5, "b0d9": 5, "381aa07a26af": 5, "ha": [6, 7, 8], "easili": [6, 8], "set": 6, "sampl": 6, "ll": [6, 8], "account": [6, 8], "python": [6, 8, 9], "haven": 6, "alreadi": 6, "standalon": 6, "initi": 6, "appli": 6, "tf": 6, "ask": [6, 7], "scylla_api_token": 6, "perform": [6, 7], "action": 6, "ye": 6, "onli": 6, "approv": 6, "scylladbcloud_clust": 6, "underwai": 6, "dashboard": [6, 8], "verifi": 6, "tab": 6, "consol": 6, "newli": 6, "favourit": 6, "learn": [7, 8, 9], "nosql": [7, 8, 9], "cours": [7, 8], "goal": 7, "fast": 7, "even": [7, 8], "sometim": 7, "duplic": 7, "around": 7, "against": 7, "domain": 7, "consid": 7, "both": 7, "often": 7, "achiev": 7, "distribut": 7, "minim": [7, 8], "number": 7, "On": 7, "hand": 7, "focu": 7, "won": 7, "avoid": 7, "write": [7, 8], "probabl": 7, "familiar": 7, "step": [7, 9], "identifi": 7, "relationship": 7, "mani": 7, "typic": 7, "than": 7, "few": 7, "question": 7, "import": 7, "oppos": 7, "earli": 7, "q1": 7, "q2": 7, "q3": 7, "q4": 7, "q5": 7, "summari": 7, "base": 7, "outcom": 7, "stage": [7, 8], "determin": 7, "highli": 7, "lesson": [7, 8], "better": [7, 8], "denorm": [7, 8], "matter": 7, "befor": 7, "proceed": 7, "high": [7, 8], "rf": 7, "choos": 7, "window": 7, "twc": 7, "reason": 7, "seri": 7, "hourli": 7, "an": [7, 8, 9], "optim": 7, "tier": 7, "fair": 7, "assumpt": 7, "slot": 7, "never": 7, "overlap": 7, "That": 7, "isol": 7, "bucket": 7, "independ": 7, "unit": 7, "reduc": 7, "overal": 7, "amplif": 7, "stc": 7, "enterpris": 7, "increment": 7, "ic": 7, "offer": 7, "accord": 7, "timestamp": 7, "timewindowcompactionstrategi": 7, "some": 7, "advanc": [7, 8], "topic": [7, 8], "cover": 7, "udt": 7, "expir": 7, "live": 7, "ttl": 7, "counter": 7, "summar": 7, "think": 7, "pai": 7, "attent": 7, "afraid": 7, "show": 8, "scratch": [8, 9], "datastor": [8, 9], "It": 8, "gather": 8, "monitor": 8, "temperatur": 8, "puls": 8, "analyz": 8, "modul": 8, "claim": 8, "report": 8, "four": 8, "respir": 8, "directli": 8, "throughput": 8, "sensit": 8, "latenc": [8, 9], "assum": 8, "sla": 8, "100k": 8, "millisecond": 8, "99th": 8, "percentil": 8, "fault": 8, "toler": 8, "goe": 8, "becom": 8, "unavail": 8, "remain": 8, "continu": 8, "terraform": [8, 9], "tutori": [8, 9], "quicker": 8, "t3": 8, "micro": 8, "smallest": 8, "java": [8, 9], "etc": 8, "javascript": [8, 9], "php": [8, 9], "rust": [8, 9], "essenti": 8, "basic": 8, "techniqu": 8, "includ": 8, "workflow": 8, "analysi": 8, "slack": 8, "channel": 8, "futur": 8, "benchmark": 8, "real": [8, 9], "world": 8, "would": 8, "intern": 8, "gatewai": 8, "impli": 8, "delta": 8, "encod": 8, "lower": 8, "resolut": 8, "less": 8, "frequent": 8, "notifi": 8, "suspici": 8, "alert": 8, "safe": 8, "zone": 8, "known": 8, "wifi": 8, "present": 8, "vital": 8, "sign": 8, "level": 8, "calori": 8, "burn": 8, "low": 9, "iot": 9, "abl": 9, "back": 9, "share": 9, "design": 9, "blog": 9, "addit": 9, "articl": 9, "deploi": 9}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"build": [0, 1, 2, 4, 5, 8], "an": [0, 1, 2, 4, 5], "iot": [0, 1, 2, 3, 4, 5, 8], "app": [0, 1, 2, 4, 5, 8], "go": 0, "introduct": [0, 8], "migrat": [0, 1, 2, 5], "sensor": [0, 1, 2, 3, 5], "server": [0, 1, 2, 3, 5], "resourc": [0, 1, 2, 3, 4, 5, 8], "java": 1, "architectur": [1, 2, 4, 5, 8], "javascript": 2, "code": 2, "structur": 2, "implement": 2, "quick": [2, 3], "start": [2, 3, 4, 6, 8], "us": [2, 3, 4, 8], "scylladb": [2, 3, 4, 6, 8], "your": [2, 8], "local": [2, 8], "machin": 2, "run": [2, 3], "scylla": [2, 4], "cloud": [2, 4, 6, 8], "output": 2, "index": 2, "j": 2, "applic": [2, 3, 7, 8], "care": 3, "pet": 3, "php": 3, "exampl": 3, "setup": 3, "command": 3, "configur": 3, "environ": 3, "initi": 3, "keyspac": 3, "web": 3, "simul": 3, "insert": 3, "data": [3, 4, 7], "nodetool": 3, "contain": [3, 4], "shell": 3, "inspect": 3, "get": [3, 6, 8], "node": 3, "ip": 3, "address": 3, "python": 4, "clone": [4, 6], "repositori": [4, 6], "instal": [4, 6], "depend": 4, "docker": 4, "skip": 4, "thi": 4, "you": 4, "connect": 4, "creat": 4, "databas": 4, "schema": 4, "gener": 4, "ingest": 4, "set": 4, "up": [4, 6], "test": 4, "rest": 4, "api": [4, 5], "rust": 5, "retriev": 5, "inform": 5, "from": 5, "deploi": [6, 8], "terraform": 6, "prerequisit": [6, 8], "cqlsh": 6, "spin": 6, "new": 6, "cluster": 6, "design": 7, "model": 7, "conceptu": 7, "workflow": 7, "queri": 7, "logic": 7, "physic": 7, "carepet": 8, "A": 8, "sampl": 8, "requir": 8, "case": 8, "perform": 8, "program": 8, "languag": 8, "addit": 8}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.todo": 2, "sphinx": 60}, "alltitles": {"Build an IoT App with Java": [[1, "build-an-iot-app-with-java"]], "Architecture": [[1, "architecture"], [4, "architecture"], [5, "architecture"], [2, "architecture"], [8, "architecture"]], "Migrate": [[1, "migrate"], [0, "migrate"], [5, "migrate"], [2, "migrate"]], "Sensor": [[1, "sensor"], [0, "sensor"], [5, "sensor"], [2, "sensor"]], "Server": [[1, "server"], [0, "server"], [5, "server"], [2, "server"]], "Resources": [[1, "resources"], [0, "resources"], [4, "resources"], [5, "resources"], [3, "resources"], [2, "resources"]], "Build an IoT App with Go": [[0, "build-an-iot-app-with-go"]], "Introduction": [[0, "introduction"], [8, "introduction"]], "Design and Data Model": [[7, "design-and-data-model"]], "Conceptual Data Model": [[7, "conceptual-data-model"]], "Application Workflow": [[7, "application-workflow"]], "Queries": [[7, "queries"]], "Logical Data Model": [[7, "logical-data-model"]], "Physical Data Model": [[7, "physical-data-model"]], "Deploy in ScyllaDB Cloud with Terraform": [[6, "deploy-in-scylladb-cloud-with-terraform"]], "Prerequisites": [[6, "prerequisites"]], "Get started": [[6, "get-started"]], "Clone the repository": [[6, "clone-the-repository"]], "Install CQLSH": [[6, "install-cqlsh"]], "Spin up a new ScyllaDB Cloud cluster": [[6, "spin-up-a-new-scylladb-cloud-cluster"]], "Build an IoT App with Python": [[4, "build-an-iot-app-with-python"]], "Clone repository and install dependencies": [[4, "clone-repository-and-install-dependencies"]], "Start Docker containers (skip this if you use Scylla Cloud)": [[4, "start-docker-containers-skip-this-if-you-use-scylla-cloud"]], "Connect to ScyllaDB and create the database schema": [[4, "connect-to-scylladb-and-create-the-database-schema"]], "Generate and ingest IoT data": [[4, "generate-and-ingest-iot-data"]], "Set up and test REST API": [[4, "set-up-and-test-rest-api"]], "Build an IoT App with Rust": [[5, "build-an-iot-app-with-rust"]], "Retrieving informations from API": [[5, "retrieving-informations-from-api"]], "Care Pet ScyllaDB PHP IoT example": [[3, "care-pet-scylladb-php-iot-example"]], "Quick Start": [[3, "quick-start"], [2, "quick-start"]], "Setup": [[3, "setup"]], "Useful Commands": [[3, "useful-commands"]], "PHP Application Commands": [[3, "php-application-commands"]], "Configuring the Environment": [[3, "configuring-the-environment"]], "Initializing Keyspace:": [[3, "initializing-keyspace"]], "Starting Web Server:": [[3, "starting-web-server"]], "Simulate Environment Sensors:": [[3, "simulate-environment-sensors"]], "Inserting Data": [[3, "inserting-data"]], "ScyllaDB Commands": [[3, "scylladb-commands"]], "Running Nodetool:": [[3, "running-nodetool"]], "Running Container Shell:": [[3, "running-container-shell"]], "Inspecting a Container": [[3, "inspecting-a-container"]], "Get Node IP Address:": [[3, "get-node-ip-address"]], "Build an IoT App with JavaScript": [[2, "build-an-iot-app-with-javascript"]], "Code Structure and Implementation": [[2, "code-structure-and-implementation"]], "Use ScyllaDB on your local machine": [[2, "use-scylladb-on-your-local-machine"]], "Run ScyllaDB on your local machine": [[2, "run-scylladb-on-your-local-machine"]], "Using Scylla Cloud": [[2, "using-scylla-cloud"], [2, "id1"], [2, "id3"]], "Output": [[2, "output"]], "migrate/index.js": [[2, "migrate-index-js"]], "Using ScyllaDB on your local machine": [[2, "using-scylladb-on-your-local-machine"], [2, "id2"]], "Using the Application": [[2, "using-the-application"]], "Getting Started with CarePet: A sample IoT App": [[8, "getting-started-with-carepet-a-sample-iot-app"]], "Requirements": [[8, "requirements"]], "Prerequisites for Deploying the Application": [[8, "prerequisites-for-deploying-the-application"]], "Use Case Requirements": [[8, "use-case-requirements"]], "Performance Requirements": [[8, "performance-requirements"]], "Deploying the Application in ScyllaDB Cloud": [[8, "deploying-the-application-in-scylladb-cloud"]], "Deploying the Application Locally": [[8, "deploying-the-application-locally"]], "Build the Application with Your Programming Language": [[8, "build-the-application-with-your-programming-language"]], "Additional Resources": [[8, "additional-resources"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/master/sitemap.xml b/master/sitemap.xml new file mode 100644 index 00000000..ff87b68f --- /dev/null +++ b/master/sitemap.xml @@ -0,0 +1,2 @@ + +https://iot.scylladb.com/stable/build-with-go.htmlhttps://iot.scylladb.com/stable/build-with-java.htmlhttps://iot.scylladb.com/stable/build-with-javascript.htmlhttps://iot.scylladb.com/stable/build-with-python.htmlhttps://iot.scylladb.com/stable/build-with-php.htmlhttps://iot.scylladb.com/stable/design-and-data-model.htmlhttps://iot.scylladb.com/stable/build-with-rust.htmlhttps://iot.scylladb.com/stable/getting-started.htmlhttps://iot.scylladb.com/stable/deploy-in-cloud.htmlhttps://iot.scylladb.com/stable/index.htmlhttps://iot.scylladb.com/stable/genindex.htmlhttps://iot.scylladb.com/stable/404.htmlhttps://iot.scylladb.com/stable/search.html \ No newline at end of file diff --git a/stable/.buildinfo b/stable/.buildinfo new file mode 100644 index 00000000..42533cc3 --- /dev/null +++ b/stable/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: b117e02212ab8f003dbfaf0c65d541e5 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/stable/.doctrees/build-with-go.doctree b/stable/.doctrees/build-with-go.doctree new file mode 100644 index 00000000..7632a325 Binary files /dev/null and b/stable/.doctrees/build-with-go.doctree differ diff --git a/stable/.doctrees/build-with-java.doctree b/stable/.doctrees/build-with-java.doctree new file mode 100644 index 00000000..97ace2cd Binary files /dev/null and b/stable/.doctrees/build-with-java.doctree differ diff --git a/stable/.doctrees/build-with-javascript.doctree b/stable/.doctrees/build-with-javascript.doctree new file mode 100644 index 00000000..72a5491c Binary files /dev/null and b/stable/.doctrees/build-with-javascript.doctree differ diff --git a/stable/.doctrees/build-with-php.doctree b/stable/.doctrees/build-with-php.doctree new file mode 100644 index 00000000..dd552c7b Binary files /dev/null and b/stable/.doctrees/build-with-php.doctree differ diff --git a/stable/.doctrees/build-with-python.doctree b/stable/.doctrees/build-with-python.doctree new file mode 100644 index 00000000..52a93b94 Binary files /dev/null and b/stable/.doctrees/build-with-python.doctree differ diff --git a/stable/.doctrees/build-with-rust.doctree b/stable/.doctrees/build-with-rust.doctree new file mode 100644 index 00000000..791d0ab5 Binary files /dev/null and b/stable/.doctrees/build-with-rust.doctree differ diff --git a/stable/.doctrees/deploy-in-cloud.doctree b/stable/.doctrees/deploy-in-cloud.doctree new file mode 100644 index 00000000..b3ee3460 Binary files /dev/null and b/stable/.doctrees/deploy-in-cloud.doctree differ diff --git a/stable/.doctrees/design-and-data-model.doctree b/stable/.doctrees/design-and-data-model.doctree new file mode 100644 index 00000000..8c82fa5c Binary files /dev/null and b/stable/.doctrees/design-and-data-model.doctree differ diff --git a/stable/.doctrees/environment.pickle b/stable/.doctrees/environment.pickle new file mode 100644 index 00000000..a0aeef57 Binary files /dev/null and b/stable/.doctrees/environment.pickle differ diff --git a/stable/.doctrees/getting-started.doctree b/stable/.doctrees/getting-started.doctree new file mode 100644 index 00000000..fc43ac6a Binary files /dev/null and b/stable/.doctrees/getting-started.doctree differ diff --git a/stable/.doctrees/index.doctree b/stable/.doctrees/index.doctree new file mode 100644 index 00000000..11187e35 Binary files /dev/null and b/stable/.doctrees/index.doctree differ diff --git a/stable/.nojekyll b/stable/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/stable/404.html b/stable/404.html new file mode 100644 index 00000000..4f7c5040 --- /dev/null +++ b/stable/404.html @@ -0,0 +1,31 @@ + + + + + + + + + ScyllaDB + + + + + + + + + + + +
      +

      404

      +

      The ScyllaDB monster ate your page!

      +

      + Home +

      +
      + + + \ No newline at end of file diff --git a/stable/CNAME b/stable/CNAME new file mode 100644 index 00000000..35a90dad --- /dev/null +++ b/stable/CNAME @@ -0,0 +1 @@ +iot.scylladb.com \ No newline at end of file diff --git a/stable/_images/cloud_screen.png b/stable/_images/cloud_screen.png new file mode 100644 index 00000000..7734a8b3 Binary files /dev/null and b/stable/_images/cloud_screen.png differ diff --git a/stable/_sources/build-with-go.md.txt b/stable/_sources/build-with-go.md.txt new file mode 100644 index 00000000..5cc87fbe --- /dev/null +++ b/stable/_sources/build-with-go.md.txt @@ -0,0 +1,179 @@ +# Build an IoT App with Go + +## Introduction + +In this section, we will walk you through the CarePet commands and explain the code behind them. + +As explained in [Getting Started with CarePet](/getting-started.md), the project is structured as follows: +- Migrate (/cmd/migrate) - Creates the CarePet keyspace and tables. +- Collar (/cmd/sensor) - Simulates a pet's collar by generating the pet's health data and pushing the data into the storage. +- Server (/cmd/server) - REST API service for tracking the pets’ health state. + + +## Migrate + +The `/migrate` command creates the keyspace and tables that will be used by the collar and server services. + +Line 25 to 27 in the `/cmd/migrate/migrate.go` file call the `createKeyspace` , `migrateKeyspace` then the `printKeyspaceMetadata` functions. + +``` +func main() { + + /// ... + + createKeyspace() + migrateKeyspace() + printKeyspaceMetadata() +} +``` + +The `createKeyspace` function creates a new session then executes the following CQL query stored in the `db.go` file: + +``` +CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' } AND durable_writes = TRUE; +``` + +``` +func createKeyspace() { + // Creates a new session + ses, err := config.Session() + if err != nil { + log.Fatalln("session: ", err) + } + defer ses.Close() + + // Executes the CREATE KEYSPACE query and checks for errors + if err := ses.Query(db.KeySpaceCQL).Exec(); err != nil { + log.Fatalln("ensure keyspace exists: ", err) + } +} +``` + +The `migrateKeyspace` function opens a new session with the `carepet` keyspace and creates the following tables in the carepet keyspace using the CQL file located in `/db/cql/care-pet-ddl.cql`: +- `owner` +- `pet` +- `sensor` +- `measurement` +- `sensor_avg` + +``` +func migrateKeyspace() { + // Create a new session with the carepet keyspace + ses, err := config.Keyspace() + if err != nil { + log.Fatalln("session: ", err) + } + defer ses.Close() + + // Execute the queries in the migration file om db/cql + if err := migrate.Migrate(context.Background(), ses, "db/cql"); err != nil { + log.Fatalln("migrate: ", err) + } +} +``` + +As the name suggests, the `printKeyspaceMetadata` function will then print the metadata related to the `carepet` keyspace and confirm that the tables were properly created. + +## Sensor + +The sensor service simulates the collar's activity. The service uses the `pet struct` and its functions defined in `sensor/pet.go` to create a new `pet` along with an `owner` and `sensorType` then saves it to the database. + +``` +func main() { + + /// ... + + // Create a new session with carepet keyspace + ses, err := config.Keyspace() + if err != nil { + log.Fatalln("session: ", err) + } + defer ses.Close() + + // Generate new pet + pet := NewPet() + + // Save new pet to the database + if err := pet.save(context.Background(), ses); err != nil { + log.Fatalln("pet save: ", err) + } + + log.Println("New owner #", pet.p.OwnerID) + log.Println("New pet #", pet.p.PetID) + + pet.run(context.Background(), ses) +} +``` + +## Server + +The server service is a REST API for tracking the pets’ health state. The service allows users to query the database via http. + +In the care-pet example, you will use `$ curl http://127.0.0.1:8000/api/owner/{id}` and expect the following response: + +``` +[{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}] +``` + +Let's first discuss the code from line 23 to 28 in `server/main.go`. + +``` +func main() { + + // ... + + api := operations.NewCarePetAPI(spec()) + server := restapi.NewServer(api) + defer server.Shutdown() + + configure(server) + server.ConfigureAPI() + + // ... + +} +``` +The `api` object represent a list of functions and codes generated by the swagger tool. Those operations are then passed to the NewServer method to configure the API and handler methods: + +``` +// ConfigureAPI configures the API and handlers. +func (s *Server) ConfigureAPI() { + if s.api != nil { + s.handler = configureAPI(s.api) + } +} +``` +One example of a handler method is the `FindOwnerByID` in `handler/owner.go`. + +``` +func FindOwnerByID(ses gocqlx.Session) operations.FindOwnerByIDHandlerFunc { + return func(params operations.FindOwnerByIDParams) middleware.Responder { + var owner model.Owner + + if err := db.TableOwner.GetQuery(ses).Bind(params.ID.String()).GetRelease(&owner); err == gocql.ErrNotFound { + // Returns FindOwnerByIDDefault with with status code 404 + return operations.NewFindOwnerByIDDefault(http.StatusNotFound) + } else if err != nil { + log.Println("find owner by id query: ", err) + // Returns FindOwnerByIDDefault with with status code 500 + return operations.NewFindOwnerByIDDefault(http.StatusInternalServerError) + } + + // Return status 200 and owner information + return &operations.FindOwnerByIDOK{Payload: &models.Owner{ + Address: owner.Address, + Name: owner.Name, + OwnerID: conv.UUID(strfmt.UUID(owner.OwnerID.String())), + }} + } +} +``` +Line 25 queries the `owner` table then saves the result in the owner object or throws a not found 404 status error. + +Line 32 returns a FindOwnerByIDOK object with code status 200 and the owner's information. + +## Resources + +* [ScyllaDB Go driver on Github](https://github.com/scylladb/gocql) +* [Go and ScyllaDB on ScyllaDB University](https://university.scylladb.com/courses/the-mutant-monitoring-system-training-course/lessons/golang-and-scylla-part-1/) +* [Scylla Go driver documentation page](https://docs.scylladb.com/stable/using-scylla/drivers/cql-drivers/scylla-go-driver.html) \ No newline at end of file diff --git a/stable/_sources/build-with-java.md.txt b/stable/_sources/build-with-java.md.txt new file mode 100644 index 00000000..3e3302eb --- /dev/null +++ b/stable/_sources/build-with-java.md.txt @@ -0,0 +1,269 @@ +# Build an IoT App with Java + +## Architecture + +In this section, we will walk you through the CarePet commands and explain the code behind them. +The project is structured as follows: + +- Migrate (`com.carepet.Migrate`) - Creates the `carepet` keyspace and tables. +- Collar (`com.carepet.Sensor`) - Generates pet health data and pushes it into the storage. +- Web app (`com.carepet.server.App`) - REST API service for tracking pets' health state. + +## Migrate + +The `./bin/migrate.sh --hosts $NODE1 --datacenter datacenter1` command executes the main function in the `Migrate` class located `Migrate.java`. The function creates the keyspace and tables used by the collar and server services. + +The following code in the `Migrate.java` file calls the `createKeyspace` , `createSchema` , and `printMetadata` functions. + +``` +public static void main(String[] args) { + final Config config = Config.parse(new Config(), args); + + final Migrate client = new Migrate(config); + client.createKeyspace(); + client.createSchema(); + client.printMetadata(); +} +``` + +Let's break down the code line by line. + +The `config` object parses the arguments passed in the migrate command. In our case it's `hosts` and `datacenter`. The `hosts` argument expects the IP address of one of the nodes. The `datacenter` argument is `datacenter1` by default but could be different if you use Scylla Cloud. The command also accepts `username` and `password` arguments if required. + +The `createKeyspace` function creates a new `CqlSession`, then executes the following CQL query stored in the `resources/care-pet-keyspace.cql` file: + +``` +public void createKeyspace() { + LOG.info("creating keyspace..."); + try (CqlSession session = connect()) { + session.execute(Config.getResource("care-pet-keyspace.cql")); + } +} +``` + +``` +CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' } AND durable_writes = TRUE; +``` + +The CQL query above creates a new keyspace named carepet, with `NetworkTopologyStrategy` as replication strategy and a replication factor of 3. +See [Scylla University](https://university.scylladb.com/courses/data-modeling/lessons/basic-data-modeling-2/topic/keyspace/) for more information about keyspaces and replication. + +The `createSchema` function opens a new session with the `carepet` keyspace and creates the following tables in the carepet keyspace using the CQL file located in `resources/care-pet-ddl.cql`: + +- `owner` +- `pet` +- `sensor` +- `measurement` +- `sensor_avg` + +``` +public void createSchema() { + LOG.info("creating table..."); + try (CqlSession session = keyspace()) { + for (String cql : Config.getResource("care-pet-ddl.cql").split(";")) { + session.execute(cql); + } + } +} +``` + +The `printMetadata` function will print the metadata related to the `carepet` keyspace and confirm that the tables are properly created. + +You can check the database structure with: + +``` +$ docker exec -it carepet-scylla1 cqlsh +cqlsh> USE carepet; +cqlsh:carepet> DESCRIBE TABLES +cqlsh:carepet> DESCRIBE TABLE pet +``` + +You should expect the following result: + +``` +CREATE TABLE carepet.pet ( +owner_id uuid, +pet_id uuid, +chip_id text, +species text, +breed text, +color text, +gender text, +address text, +age int, +name text, +weight float, +PRIMARY KEY (owner_id, pet_id) +) WITH CLUSTERING ORDER BY (pet_id ASC) +AND bloom_filter_fp_chance = 0.01 +AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'} +AND comment = '' +AND compaction = {'class': 'SizeTieredCompactionStrategy'} +AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'} +AND crc_check_chance = 1.0 +AND dclocal_read_repair_chance = 0.1 +AND default_time_to_live = 0 +AND gc_grace_seconds = 864000 +AND max_index_interval = 2048 +AND memtable_flush_period_in_ms = 0 +AND min_index_interval = 128 +AND read_repair_chance = 0.0 +AND speculative_retry = '99.0PERCENTILE'; +``` + +## Sensor + +The sensor service simulates the collar's activity. You can use the following command to run the sensor service: + +``` +$ mvn package +$ NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +$ ./bin/sensor.sh --hosts $NODE1 --datacenter datacenter1 --measure PT1M --buffer-interval PT1M +``` + +The above command executes `Sensor.java` and the following `main` function: + +``` +public static void main(String[] args) { + final Sensor client = new Sensor(Config.parse(new SensorConfig(), args)); + client.save(); + client.run(); + } +} +``` + +First, we create a client object, an instance of the Sensor class. Like in the `Migrate` class, we parse args using the `Config.parse()` method to connect to the database. + +In the `Sensor` constructor, a random ID is attributed to the `owner`, `pet`, and `sensors`. + +``` +public Sensor(SensorConfig config) { + this.config = config; + + this.owner = Owner.random(); + this.pet = Pet.random(this.owner.getOwnerId()); + this.sensors = new com.carepet.model.Sensor[SensorType.values().length]; + for (int i = 0; i < this.sensors.length; i++) { + this.sensors[i] = com.carepet.model.Sensor.random(this.pet.getPetId()); + } +} +``` + +The `client.save()` method connects to the datbase and saves the generated `owner`, `pet`, and the `sensors`. + +``` +private void save() { + try (CqlSession session = keyspace()) { + // Connect to the database + Mapper m = Mapper.builder(session).build(); + + LOG.info("owner = " + owner); + LOG.info("pet = " + pet); + + m.owner().create(owner); + m.pet().create(pet); + + for (com.carepet.model.Sensor s : sensors) { + LOG.info("sensor = " + s); + + m.sensor().create(s); + } + } +} +``` + +The `client.run()` generates random data and pushes it to the database. In this code, we are using `PreparedStatement` to define the query and `BatchStatementBuilder` to run multiple queries at the same time. See the [Scylla Java Driver documentation] (https://java-driver.docs.scylladb.com/stable/manual/core/statements/prepared/) for details on `PreparedStatement`. + +``` +private void run() { + try (CqlSession session = keyspace()) { + PreparedStatement statement = session.prepare("INSERT INTO measurement (sensor_id, ts, value) VALUES (?, ?, ?)"); + BatchStatementBuilder builder = new BatchStatementBuilder(BatchType.UNLOGGED); + + List ms = new ArrayList<>(); + Instant prev = Instant.now(); + + while (true) { + while (Duration.between(prev, Instant.now()).compareTo(config.bufferInterval) < 0) { + if (!sleep(config.measurement)) { + return; + } + + for (com.carepet.model.Sensor s : sensors) { + Measure m = readSensorData(s); + ms.add(m); + LOG.info(m.toString()); + } + } + + prev = prev.plusMillis((Duration.between(prev, Instant.now()).toMillis() / config.bufferInterval.toMillis()) * config.bufferInterval.toMillis()); + + LOG.info("pushing data"); + // this is simplified example of batch execution. standard + // best practice is to batch values that end up in the same partition: + // https://www.scylladb.com/2019/03/27/best-practices-for-scylla-applications/ + for (Measure m : ms) { + builder = builder.addStatement(statement.bind(m.getSensorId(), m.getTs(), m.getValue())); + } + + session.execute(builder.build()); + + builder.clearStatements(); + ms.clear(); + } + } +} +``` + +## Server + +The server service is a REST API for tracking the pets’ health state. The service allows you to query the database via HTTP. + +Run the following commands to start the server: + +``` +$ mvn package +$ NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +$ ./bin/server.sh --hosts $NODE1 --datacenter datacenter1 +``` + +In the care-pet example, run: + + `$ curl http://127.0.0.1:8000/api/owner/{id}`. + + You can expect the following response: + +``` + +[{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}] + +``` + +The controller is defined in `ModelController.java`, and implements the GET methods to access owners, pets and sensors data. + +The server also aggregates the data and saves it to the database in the sensor_avg table: + +``` + +// saveAggregate saves the result monotonically sequentially to the database +private void saveAggregate(UUID sensorId, List data, int prevAvgSize, LocalDate day, LocalDateTime now) { +// if it's the same day, we can't aggregate current hour +boolean sameDate = now.getDayOfYear() == day.getDayOfYear(); +int current = now.getHour(); + + for (int hour = prevAvgSize; hour < data.size(); hour++) { + if (sameDate && hour >= current) { + break; + } + + mapper.sensorAvg().create(new SensorAvg(sensorId, day, hour, data.get(hour))); + } + } + +``` + +## Resources + +* [Scylla Java driver documentation](https://java-driver.docs.scylladb.com/stable/) +* [ScyllaDB Java driver on Github](https://github.com/scylladb/java-driver/) +* [ScyllaDB University: Coding with Java](https://university.scylladb.com/courses/the-mutant-monitoring-system-training-course/lessons/coding-with-java-part-1/) \ No newline at end of file diff --git a/stable/_sources/build-with-javascript.md.txt b/stable/_sources/build-with-javascript.md.txt new file mode 100644 index 00000000..ede64002 --- /dev/null +++ b/stable/_sources/build-with-javascript.md.txt @@ -0,0 +1,567 @@ +# Build an IoT App with JavaScript + +## Architecture + +In this section, we will walk you through the CarePet commands and explain the code behind them. +The project is structured as follows: + +![Build your first ScyllaDB Powered App - Raouf](https://user-images.githubusercontent.com/13738772/158383650-0dfcc9d0-68b5-457a-a043-27f6cda12de3.jpg) + +- migrate (`npm run migrate`) - Creates the `carepet` keyspace and tables. +- collar (`npm run sensor`) - Generates pet health data and pushes it into the storage. +- web app (`npm run dev`) - REST API service for tracking pets' health state. + +## Code Structure and Implementation + +The code package structure is as follows: + +| Name | Purpose | +| ------------ | ----------------------------------- | +| / | web application backend | +| /api | API spec | +| /cmd | applications executables | +| /cmd/migrate | install database schema | +| /cmd/sensor | Simulates the pet's collar | +| /config | database configuration | +| /db | database handlers (gocql/x) | +| /db/cql | database schema | +| /handler | REST API handlers | +| /model | application models and ORM metadata | + +## Quick Start + +Prerequisites: + +- [NodeJS](https://nodejs.org/en/) tested with v17.0.1 +- [NPM](https://www.npmjs.com/) tested with v8.1.0 +- [docker](https://www.docker.com/) (not required if you use Scylla Cloud) +- [docker-compose](https://docs.docker.com/compose/) (not required if you use Scylla Cloud) + + +Clone the repository and change to `javascript` directory: +``` +git clone git@github.com:scylladb/care-pet.git +cd javascript +``` + +Make sure to install all NodeJS dependencies with: + + $ npm install + +## Use ScyllaDB on your local machine + +To run a local ScyllaDB cluster consisting of three nodes with +the help of `docker` and `docker-compose` execute: + + $ docker-compose up -d + +Docker-compose will spin up three nodes: `carepet-scylla1`, `carepet-scylla2`, +and `carepet-scylla3`. You can access them with the `docker` command. + +Execute the following nodetool command: + + $ docker exec -it carepet-scylla1 nodetool status + +## Migrate + +### Run ScyllaDB on your local machine + +Once all the nodes are in UN - Up Normal status, run the commands below. + +The following command allows you to get the node IP address: + +``` +docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1 +``` + +The following commands execute the migrate `main` function. + +``` +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +npm run migrate -- --hosts $NODE1 +``` +You can check the database structure with: + +``` +docker exec -it carepet-scylla1 cqlsh +``` + +### Using Scylla Cloud + +If you are using Scylla Cloud, use the the following command to run the `migrate` service: + +``` +npm run migrate -- --hosts [NODE-IP] --username [USERNAME] --password[PASSWORD] +``` + +Replace the NODE-IP, USERNAME, and PASSWORD with the information provided in your cluster on https://cloud.scylladb.com. + +## Output + +Expected output: +``` +2020/08/06 16:43:01 Bootstrap database... +2020/08/06 16:43:13 Keyspace metadata = {Name:carepet DurableWrites:true StrategyClass:org.apache.cassandra.locator.NetworkTopologyStrategy StrategyOptions:map[datacenter1:3] Tables:map[gocqlx_migrate:0xc00016ca80 measurement:0xc00016cbb0 owner:0xc00016cce0 pet:0xc00016ce10 sensor:0xc00016cf40 sensor_avg:0xc00016d070] Functions:map[] Aggregates:map[] Types:map[] Indexes:map[] Views:map[]} +``` + +You can check the database structure with: + +`docker run -it --rm --entrypoint cqlsh scylladb/scylla -u [USERNAME] -p [PASSWORD] [NODE-IP]` + +Note: use `-u [USERNAME]` and `-p [PASSWORD]` if you are using Scylla Cloud. + +Once you connect to cqlsh, run the following commands: + +#. Run `DESCRIBE KEYSPACES`. + +Expected output: +``` +carepet system_schema system_auth system system_distributed system_traces +``` +then, +``` + carepet; +DESCRIBE TABLES +``` +Expected output: + +`pet sensor_avg gocqlx_migrate measurement owner sensor` + +#. Run `DESCRIBE TABLE pet`. + +Expected output: +``` +CREATE TABLE carepet.pet ( + owner_id uuid, + pet_id uuid, + address text, + age int, + breed text, + chip_id text, + color text, + gender text, + name text, + species text, + weight float, + PRIMARY KEY (owner_id, pet_id) + ) WITH CLUSTERING ORDER BY (pet_id ASC) + AND bloom_filter_fp_chance = 0.01 + AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'} + AND comment = '' + AND compaction = {'class': 'SizeTieredCompactionStrategy'} + AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'} + AND crc_check_chance = 1.0 + AND dclocal_read_repair_chance = 0.1 + AND default_time_to_live = 0 + AND gc_grace_seconds = 864000 + AND max_index_interval = 2048 + AND memtable_flush_period_in_ms = 0 + AND min_index_interval = 128 + AND read_repair_chance = 0.0 + AND speculative_retry = '99.0PERCENTILE'; +``` + +#. Run `exit` to exit the cqlsh. + +### migrate/index.js + +The above commands execute the main function in the `cmd/migrate/index.js`. The function creates the keyspace and tables that you need to run the collar and server services. + +The following code in the `cmd/migrate/index.js` creates a new session, then calls the `create_keyspace` and `migrate` functions. + +``` +migrate/index.js + +async function main() { + // Parse the command arguments: --hosts --username and --password + const options = config('migrate').parse().opts(); + + // Create a new session with options + const client = await getClient(options); + + // Create a keyspace + await client.execute(cql.KEYSPACE); + + // Create the tables + for (const query of cql.MIGRATE) { + log.debug(`query = ${query}`); + await client.execute(query); + } + + return client; +} +``` +Let's break down the code above. + +The `getClient` function takes the options as a parameter and creates a new session. + +``` +// src/db.js + +async function getClient(config, keyspace) { + const client = new cassandra.Client({ + contactPoints: config.hosts, + authProvider: new cassandra.auth.PlainTextAuthProvider( + config.username, + config.password + ), + localDataCenter: 'datacenter1', + keyspace, + }); + + await client.connect(); + + return client; +} +``` + +`await client.execute(cql.KEYSPACE);` creates a keyspace as defined in `cql/keyspace.cql`: + +``` +CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' }; +``` + +The CQL query above creates a new keyspace named carepet, with `NetworkTopologyStrategy` as replication strategy and a replication factor of 3. +See [Scylla University](https://university.scylladb.com/courses/data-modeling/lessons/basic-data-modeling-2/topic/keyspace/) for more information about keyspaces and replication. + +Finally, the code loops through all the queries listed in `cql/migrate.cql` to create the tables you need for the project. + +``` +CREATE TABLE IF NOT EXISTS carepet.owner +( + owner_id UUID, + address TEXT, + name TEXT, + PRIMARY KEY (owner_id) +); + +... +``` + +You can check the database structure. Connect to your local ScyllaDB instance using: + +`docker exec -it carepet-scylla1 cqlsh` + +With Scylla Cloud, use: +``` +docker run -it --rm --entrypoint cqlsh scylladb/scylla -u [USERNAME] -p [PASSWORD] [NODE-IP] +``` + +Once connected to your machine, run the following commands: + +``` +cqlsh> USE carepet; +cqlsh:carepet> DESCRIBE TABLES +cqlsh:carepet> DESCRIBE TABLE pet +``` + +You should expect the following result: + +``` +CREATE TABLE carepet.pet ( + owner_id uuid, + pet_id uuid, + chip_id text, + species text, + breed text, + color text, + gender text, + address text, + age int, + name text, + weight float, + PRIMARY KEY (owner_id, pet_id) +) WITH CLUSTERING ORDER BY (pet_id ASC) + AND bloom_filter_fp_chance = 0.01 + AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'} + AND comment = '' + AND compaction = {'class': 'SizeTieredCompactionStrategy'} + AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'} + AND crc_check_chance = 1.0 + AND dclocal_read_repair_chance = 0.1 + AND default_time_to_live = 0 + AND gc_grace_seconds = 864000 + AND max_index_interval = 2048 + AND memtable_flush_period_in_ms = 0 + AND min_index_interval = 128 + AND read_repair_chance = 0.0 + AND speculative_retry = '99.0PERCENTILE'; +``` + +## Sensor + +The sensor service simulates the collar's activity and periodically saves data to the database. Use the below commands to run the sensor service: + +### Using ScyllaDB on your local machine +``` +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +npm run sensor -- --hosts $NODE1 --measure 5s --buffer-interval 1m +``` + +### Using Scylla Cloud +``` +npm run sensor -- --hosts [NODE-IP] --username [USERNAME] --password [PASSWORD] --measure 5s --buffer-interval 1m +``` +Replace the NODE-IP, USERNAME, and PASSWORD with the information provided in your cluster on https://cloud.scylladb.com. + +Expected output: +``` +2020/08/06 16:44:33 Welcome to the Pet collar simulator +2020/08/06 16:44:33 New owner # 9b20764b-f947-45bb-a020-bf6d02cc2224 +2020/08/06 16:44:33 New pet # f3a836c7-ec64-44c3-b66f-0abe9ad2befd +2020/08/06 16:44:33 sensor # 48212af8-afff-43ea-9240-c0e5458d82c1 type L new measure 51.360596 ts 2020-08-06T16:44:33+02:00 +2020/08/06 16:44:33 sensor # 2ff06ffb-ecad-4c55-be78-0a3d413231d9 type R new measure 36 ts 2020-08-06T16:44:33+02:00 +2020/08/06 16:44:33 sensor # 821588e0-840d-48c6-b9c9-7d1045e0f38c type L new measure 26.380281 ts 2020-08-06T16:44:33+02:00 +... +``` + +The above command executes `cmd/sensor/index.js` and takes the following as arguments: + +- `hosts` : the IP address of the ScyllaDB node. +- `username`: when Password Authentication enabled +- `password`: when Password Authentication enabled +- `measure`: the interval between to sensor measures. +- `buffer-interval`: the interval between two database queries. + +``` +// sensor/index.js + +async function main() { + // Parse command arguments + const options = cli(config('sensor simulator')) + .parse() + .opts(); + + const bufferInterval = parseDuration(options.bufferInterval); + const measure = parseDuration(options.measure); + + // ... + + // Connect to cluster using a keyspace + const client = await getClientWithKeyspace(options); + + // Generate random owner, pet and sensors IDs + const { owner, pet, sensors } = randomData(); + + await saveData(client, owner, pet, sensors); + + // Generate sensor data and save them to the database periodically + await runSensorData( + client, + { + bufferInterval, + measure, + }, + sensors + ); + + return client; +} +``` + +Just like in `migrate/index.js`, the function parses the `npm run sensor` command arguments. +Now you can create a new session `client` using `carepet` keyspace. + +``` +// db.js + +async function getClientWithKeyspace(config) { + return getClient(config, KEYSPACE); +} +``` + +The `saveData` method connects to the database and saves random `owner`, `pet`, and `sensors` to the database. + +``` +// sensor/index.js + +async function saveData(client, owner, pet, sensors) { + await client.execute(insertQuery(Owner), owner, { prepare: true }); + log.info(`New owner # ${owner.owner_id}`); + + await client.execute(insertQuery(Pet), pet, { prepare: true }); + log.info(`New pet # ${pet.pet_id}`); + + for (let sensor of sensors) { + await client.execute(insertQuery(Sensor), sensor, { prepare: true }); + log.info(`New sensor # ${sensor.sensor_id}`); + } +} +``` + +The `runSensorData` generates random data and inserts it to the database every `buffer_interval`. Note that we are inserting the data to the database using a `batch`. + +``` +async function runSensorData(client, { bufferInterval, measure }, sensors) { + let last = moment(); + while (true) { + const measures = []; + while (moment().diff(last) < bufferInterval) { + await delay(measure); + + measures.push( + ...sensors.map(sensor => { + const measure = readSensorData(sensor); + log.info( + `sensor # ${sensor.sensor_id} type ${sensor.type} new measure ${ + measure.value + } ts ${moment(measure.ts).toISOString()}` + ); + + return measure; + }) + ); + } + + last = last.add( + measure.valueOf() * (moment().diff(last).valueOf() / measure.valueOf()) + ); + + log.info('Pushing data'); + + const batch = measures.map(measure => ({ + query: insertQuery(Measure), + params: measure, + })); + + await client.batch(batch, { prepare: true }); + } +} +``` + +## Server + +The server service is a REST API for tracking the pets’ health state. The service allows you to query the database via HTTP. + +Run the following commands to start the server: + +### Using ScyllaDB on your local machine +``` +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +npm run dev -- --hosts $NODE1 +``` + +### Using Scylla Cloud +``` +npm run dev -- --hosts [NODE-IP] --username [USERNAME] --password [PASSWORD] +``` + +Expected output: + +``` +2020/08/06 16:45:58 Serving care pet at http://127.0.0.1:8000 +``` + +The `src/index.js` main function mounts the api on `/api` and defines the routes. + +``` +// src/index.js + +async function main() { + const options = config('care-pet').parse().opts(); + + log.debug(`Configuration = ${JSON.stringify(options)}`); + + const client = await getClientWithKeyspace(options); + + app.get(owner.ROUTE, asyncHandler(owner.handler(client))); + app.get(pets.ROUTE, asyncHandler(pets.handler(client))); + app.get(sensors.ROUTE, asyncHandler(sensors.handler(client))); + app.get(measures.ROUTE, asyncHandler(measures.handler(client))); + app.get(avg.ROUTE, asyncHandler(avg.handler(client))); + + app.listen(8000, () => { + log.info('Care-pet server started on port 8000!'); + }); +} +``` + +## Using the Application  + +Open a different terminal to send an HTTP request from the CLI: + +`curl -v http://127.0.0.1:8000/` + +Expected output: + + > GET / HTTP/1.1 + > Host: 127.0.0.1:8000 + > User-Agent: curl/7.71.1 + > Accept: */* + >  + * Mark bundle as not supporting multiuse + < HTTP/1.1 404 Not Found + < Content-Type: application/json + < Date: Thu, 06 Aug 2020 14:47:41 GMT + < Content-Length: 45 + < Connection: close + <  + * Closing connection 0 + {"code":404,"message":"path / was not found"} + +The JSON with the 404 at the end indicates expected behavior. +To read an owner's data use the previously saved owner_id as follows: + +`curl -v http://127.0.0.1:8000/api/owner/{owner_id}` + +For example: + +`curl http://127.0.0.1:8000/api/owner/a05fd0df-0f97-4eec-a211-cad28a6e5360` + +Expected result: + + {"address":"home","name":"gmwjgsap","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360"}  + +To list the owner's pets, run: + +`curl -v http://127.0.0.1:8000/api/owner/{owner_id}/pets` + +For example: + +`curl http://127.0.0.1:8000/api/owner/a05fd0df-0f97-4eec-a211-cad28a6e5360/pets` + +Expected output: + +`[{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}]` + +To list each pet's sensor, run: + +`curl -v curl -v http://127.0.0.1:8000/api/pet/{pet_id}/sensors` + +For example: + +`curl http://127.0.0.1:8000/api/pet/cef72f58-fc78-4cae-92ae-fb3c3eed35c4/sensors` + +``` +[{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d","type":"L"},{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"5c70cd8a-d9a6-416f-afd6-c99f90578d99","type":"R"},{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"fbefa67a-ceb1-4dcc-bbf1-c90d71176857","type":"L"}] +``` + +To review the data from a specific sensor: + +`curl http://127.0.0.1:8000/api/sensor/{sensor_id}/values?from=2006-01-02T15:04:05Z07:00&to=2006-01-02T15:04:05Z07:00` + +For example: + +`curl http://127.0.0.1:8000/api/sensor/5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d/values\?from\="2020-08-06T00:00:00Z"\&to\="2020-08-06T23:59:59Z"` + +expected output: + +`[51.360596,26.737432,77.88015,...]` + +To read the pet's daily average per sensor, use: + +`curl http://127.0.0.1:8000/api/sensor/{sensor_id}/values/day/{date}` + +For example: + +`curl -v http://127.0.0.1:8000/api/sensor/5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d/values/day/2020-08-06` + +Expected output: + +`[0,0,0,0,0,0,0,0,0,0,0,0,0,0,42.55736]` + +## Resources + +* [Getting Started with ScyllaDB Cloud Using Node.js](https://www.scylladb.com/2022/03/14/getting-started-with-scylladb-cloud-using-node-js-part-1/) +* [ScyllaDB University: Coding with Node.js](https://university.scylladb.com/courses/using-scylla-drivers/lessons/scylla-and-node-js/) +* [NodeJS driver on Github (third-party)](https://github.com/datastax/nodejs-driver/) \ No newline at end of file diff --git a/stable/_sources/build-with-php.md.txt b/stable/_sources/build-with-php.md.txt new file mode 100644 index 00000000..a4dbd075 --- /dev/null +++ b/stable/_sources/build-with-php.md.txt @@ -0,0 +1,410 @@ +# Care Pet ScyllaDB PHP IoT example + +This example project demonstrates a generic IoT use case for ScyllaDB in PHP. + +Here you will find a list of possible drivers to integrate with. + +| PHP Version | Driver | +|--------------|-------------------------------------------------------------------------------------| +| PHP 7.1 | [DataStax PHP Driver](https://github.com/datastax/php-driver) | +| PHP 8.2 [x] | [ScyllaDB PHP Driver (community)](https://github.com/he4rt/scylladb-php-driver) | + +You will need to build the driver following the instructions of each repository. We strongly recommend that you go for +PHP 8.x since this project still being maintained and developed by community itself. + +The documentation for this application and the guided exercise is [here](getting-started.md). + +## Quick Start + +The application allows the tracking of the pets health indicators and it consist in a CLI of three parts: + +| Command | Description | +|---------------------|------------------------------------------------------------| +| php scylla migrate | creates the `carepet` keyspace and tables | +| php scylla simulate | generates a pet health data and pushes it into the storage | +| php scylla serve | REST API service for tracking pets health state | + +Prerequisites: + +- [docker](https://www.docker.com/) +- [docker-compose](https://docs.docker.com/compose/) + +## Setup + +To run a local **ScyllaDB cluster** consisting of three nodes and the **PHP Environment** with +the help of `docker` and `docker-compose` execute: + +```shell +$ docker-compose up -d +``` + +Docker-compose will spin up three nodes which are: + +- carepet-scylla1 +- carepet-scylla2 +- carepet-scylla3 + +If you want to see your containers running, run the `docker ps` command, and you should see something like this: + +```shell +$ docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +4e351dfe3987 scylladb/scylla "/docker-entrypoint.…" 1 minute ago Up 1 minute 22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp carepet-scylla2 +9e7e4d3992df scylladb/scylla "/docker-entrypoint.…" 1 minute ago Up 1 minute 22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp carepet-scylla3 +7e2b1b94389b scylladb/scylla "/docker-entrypoint.…" 1 minute ago Up 1 minute 22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp carepet-scylla1 +``` + +> If you have any error regarding "premature connection", restart your docker instance and wait a minute until +> your ScyllaDB connection be established. + +### Useful Commands + +Here's a list of everything that you can execute and make your own research through the application. + +#### PHP Application Commands + +These commands you can execute by `entering the container` or through `docker exec` remotely: + +##### Configuring the Environment + +Make a copy of `.env.example` and name it `.env`. This file will store your application secrets. + +````shell +$ cp .env.example .env +```` + +By default, the config to connect on your local ScyllaDB instances will be ready to use. + +``` +# Development +DB_KEYSPACE="carepet" +DB_NODES="localhost" +DB_USERNAME="" +DB_PASSWORD="" +DB_PORT=9042 + +# Production (Cloud) +#DB_KEYSPACE="carepet" +#DB_NODES="node-0.aws_sa_east_1.c106d1ac5f3117a20bf0.clusters.scylla.cloud" +#DB_USERNAME="scylla" +#DB_PASSWORD="p50bonFq8cuxwXS" +#DB_PORT=9042 +``` + +> If you want to use ScyllaDB Cloud, remember to change at your keyspace the **Replication Factor** related to +> for each environment. + +##### Initializing Keyspace: + +First, let's create our keyspace using CQLSH. + +```shell +$ docker exec -it carepet-scylla1 cqlsh +Connected to at 10.10.5.2:9042. +[cqlsh 5.0.1 | Cassandra 3.0.8 | CQL spec 3.3.1 | Native protocol v4] +Use HELP for help. +cqlsh> CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '2' }; +cqlsh> +``` + +Then you can run the CLI command to migrate all your tables inside the keyspace. + +```shell +$ php scylla migrate +[INFO] Fetching Migrations... +[INFO] Migrated: /var/www/migrations/1-create_keyspace.cql +[INFO] Migrated: /var/www/migrations/2-create_owner_table.cql +[INFO] Migrated: /var/www/migrations/3-create_pets_table.cql +[INFO] Migrated: /var/www/migrations/4-create_sensors_table.cql +[INFO] Migrated: /var/www/migrations/5-create_measurements_table.cql +[INFO] Migrated: /var/www/migrations/6-create_sensor_avg_table.cql +[INFO] Done :D +``` + +##### Starting Web Server: + +```shell +$ php scylla serve +[INFO] CarePet Web started! +[INFO] Development Server: http://0.0.0.0:8000 +[Thu Jan 5 17:32:01 2023] PHP 7.4.33 Development Server (http://0.0.0.0:8000) started +``` + +##### Simulate Environment Sensors: + +```shell +$ php scylla simulate +[INFO] Starting Sensor simulator... +[INFO] Batch: 0 +[INFO] Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1 +[INFO] Pet: 14d9f304-5600-34af-8622-3d4505d617d7 | Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1 +[INFO] Sensor: 869bd01e-e0ba-364f-bbfb-8c7c496a3318 (R) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 +[INFO] Sensor: c86f63b0-1439-3404-8750-b71b90a685cb (L) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 +[INFO] Sensor: e0550426-8832-3d17-9025-77726b3009c5 (P) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 +[INFO] Sensor: bf960c81-8e0f-3012-b50d-18596b50db18 (P) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 +[INFO] Sensor: 933245de-812e-34e4-8d50-2ab072726217 (T) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 +[INFO] Pet: 319ec566-d6b0-3868-ac5e-76253ee7c236 | Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1 +[INFO] ... +``` + +````php +final class SimulateCommand extends AbstractCommand +{ + + public function __construct( + private readonly OwnerRepository $ownerRepository, + private readonly PetRepository $petRepository, + private readonly SensorRepository $sensorRepository + ) + { + } + + const AMOUNT_BASE = 50000; + + public function __invoke(array $args = []): int + { + $this->info('Starting Sensor simulator...'); + foreach (range(0, self::AMOUNT_BASE) as $i) { + $this->info("Batch: " . $i); + [$ownerDTO, $petsDTO] = $this->generateFakeData(); + + $this->ownerRepository->create($ownerDTO); + $this->info(sprintf('Owner %s', $ownerDTO->id)); + + $petsDTO->each(function ($petDTO) { + $this->info(sprintf('Pet: %s | Owner %s', $petDTO->id->uuid(), $petDTO->ownerId)); + $this->petRepository->create($petDTO); + + SensorFactory::makeMany(5, ['pet_id' => $petDTO->id]) + ->each($this->handleSensors()); + }); + } + $this->info('Done :D'); + + return self::SUCCESS; + } + + private function generateFakeData(): array + { + $ownerDTO = OwnerFactory::make(); + $petsDTO = PetFactory::makeMany(5, ['owner_id' => $ownerDTO->id]); + + return [$ownerDTO, $petsDTO]; + } + + private function handleSensors(): Closure + { + return function (SensorDTO $sensorDTO) { + $this->sensorRepository->create($sensorDTO); + $this->info(sprintf( + 'Sensor: %s (%s) | Pet %s', + $sensorDTO->id, + $sensorDTO->type->name, + $sensorDTO->petId + )); + }; + } +} +```` + +##### Inserting Data + +You can use `Cassandra::cluster()` and setup your cluster. + +````php +use Cassandra; +use Cassandra\Cluster; +use Cassandra\Cluster\Builder; +use Cassandra\FutureRows; +use Cassandra\Session; +use Cassandra\SimpleStatement; + +class Connector +{ + public Builder $connectionBuilder; + public Cluster $cluster; + public Session $session; + public SimpleStatement $query; + + const BASE_TIMEOUT = 10; + + public function __construct(array $config) + { + $this->connectionBuilder = Cassandra::cluster() + ->withContactPoints($config['nodes']) + ->withDefaultConsistency($config['consistency_level']) + ->withPort($config['port']); + + if (!empty($config['username'] && !empty($config['password']))) { + $this->connectionBuilder = $this->connectionBuilder->withCredentials($config['username'], $config['password']); + } + $this->cluster = $this->connectionBuilder->build(); + + $this->session = $this->cluster->connect($config['keyspace']); + } + + public function setKeyspace(string $keyspace = ''): self + { + $this->session->close(self::BASE_TIMEOUT); + $this->session = $this->cluster->connect($keyspace); + + return $this; + } + + public function prepare(string $query): self + { + $this->query = new SimpleStatement($query); + + return $this; + } + + public function execute(): FutureRows + { + return $this->session->executeAsync($this->query, []); + } +} + +```` + +````php +use App\Core\Entities\AbstractDTO; +use Cassandra\Rows; + +abstract class AbstractRepository +{ + public string $table = ''; + + public string $primaryKey = ''; + + public Connector $connection; + + public array $keys = []; + + public function __construct(Connector $connector) + { + $this->connection = $connector; + } + + public function getById(string $id): Rows + { + $query = sprintf("SELECT * FROM %s WHERE %s = %s", $this->table, $this->primaryKey, $id); + + return $this->connection + ->prepare($query) + ->execute() + ->get(Connector::BASE_TIMEOUT); + } + + public function all(): Rows + { + return $this->connection + ->prepare(sprintf('SELECT * FROM %s', $this->table)) + ->execute() + ->get(Connector::BASE_TIMEOUT); + } + + public function create(AbstractDTO $dto): void + { + $keys = array_keys($dto->toDatabase()); + $dataValues = array_values($dto->toDatabase()); + + foreach ($dataValues as $key => $value) { + if (is_string($value) && !in_array($keys[$key], $this->keys)) { + $value = addslashes($value); + $dataValues[$key] = "'$value'"; + } + } + + $query = sprintf( + "INSERT INTO %s (%s) VALUES (%s)", + $this->table, + implode(', ', $keys), + implode(', ', $dataValues) + ); + + + $this->connection + ->prepare($query) + ->execute(); + } +} +```` + +#### ScyllaDB Commands + +##### Running Nodetool: + +```shell +$ docker exec -it carepet-scylla1 nodetool status +======================= +Datacenter: datacenter1 +======================= +Status=Up/Down +|/ State=Normal/Leaving/Joining/Moving +-- Address Load Tokens Owns Host ID Rack +UN 10.10.5.2 212 KB 256 ? f6121e15-48df-4b31-b725-3ad2795b8b94 rack1 +UN 10.10.5.3 1.06 MB 256 ? 871795f3-67d2-47ba-83ef-15714b89c02a rack1 +UN 10.10.5.4 1.06 MB 256 ? cbe74a63-2cf4-41c2-bf7f-c831c0d2689f rack1 +``` + +##### Running Container Shell: + +```shell +$ docker exec -it carepet-scylla1 bash + + _____ _ _ _____ ____ + / ____| | | | | __ \| _ \ + | (___ ___ _ _| | | __ _| | | | |_) | + \___ \ / __| | | | | |/ _` | | | | _ < + ____) | (__| |_| | | | (_| | |__| | |_) | + |_____/ \___|\__, |_|_|\__,_|_____/|____/ + __/ | + |___/ +Nodetool: + nodetool help +CQL Shell: + cqlsh +More documentation available at: + http://www.scylladb.com/doc/ + +root@7e2b1b94389b:/# +``` + +##### Inspecting a Container + +_You can inspect any node by means of the `docker inspect` command as follows. For example:_ + +```shell +$ docker inspect carepet-scylla1 +[ + { + "Id": "7e2b1b94389b36c494093db8e119c2b8c5167339f20e03d9bfa070e8e46f8430", + "Created": "2023-01-05T17:36:59.038609825Z", + "Path": "/docker-entrypoint.py", + "Args": [ + "--smp", + "1" + ], + "State": { + "Status": "running", + "Running": true, + "Paused": false, + "Restarting": false + ... + } + } +] +``` + +###### Get Node IP Address: + +```shell +$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1 +10.10.5.2 +``` + +### Resources + +* [ScyllaDB PHP driver for PHP 8.2.x on Github (maintained by community)](https://github.com/he4rt/scylladb-php-driver) + +* [Driver for PHP 7.1 (third-party, not actively maintained](https://github.com/datastax/php-driver) diff --git a/stable/_sources/build-with-python.md.txt b/stable/_sources/build-with-python.md.txt new file mode 100644 index 00000000..202383e6 --- /dev/null +++ b/stable/_sources/build-with-python.md.txt @@ -0,0 +1,256 @@ +# Build an IoT App with Python + +## Architecture + +This section will walk through and explain the code for the different commands. +As explained in the Getting Started page, the project is structured as follow: + +* Migrate (`python src/migrate.py`) - creates keyspace and tables in ScyllaDB +* Sensor (`python src/sensor.py`) - generates random IoT data and inserts it into ScyllaDB +* API (`python src/api.py`) - REST API service to fetch data from ScyllaDB + +## Clone repository and install dependencies +Clone the repository and open the root directory of the project: +```bash +git clone https://github.com/scylladb/care-pet +cd care-pet/python +``` + +Create a new virtual environment and activate it: +```bash +virtualenv env +source env/bin/activate +``` + +Install all Python dependencies: +```bash +pip install -r requirements.txt +``` + +## Start Docker containers (skip this if you use Scylla Cloud) +Spin up a local ScyllaDB cluster with three nodes using `docker` and `docker-compose`: +```bash +docker-compose up -d + +Creating carepet-scylla3 ... done +Creating carepet-scylla2 ... done +Creating carepet-scylla1 ... done +``` + +This command starts three ScyllaDB nodes in containers: +* `carepet-scylla1` +* `carepet-scylla2` +* `carepet-scylla3` + +You can inspect any of these nodes by using the `docker inspect` command, +for example: +```bash +docker inspect carepet-scylla1 + +[ + { + "Id": "c87128b7d0ca4a31a84da78875c8b4181283c34783b6b0a78bffbacbbe45fcc2", + "Created": "2023-01-08T21:17:13.212585687Z", + "Path": "/docker-entrypoint.py", + "Args": [ + "--smp", + "1" + ], + "State": { + "Status": "running", + "Running": true, +... +``` + +## Connect to ScyllaDB and create the database schema +To connect to your ScyllaDB storage within the container, you need to know the +IP address of one of the running nodes. +This is how you can get the IP address of the first node running in the container: +```bash +docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1 +``` + +You will need to reference this value multiple times later so if it's easier +for you can save it as a variable `NODE1`: +```bash +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +``` + +Now you can run the migration script that creates the required keyspace and tables: +```bash +python src/migrate.py -h $NODE1 + +Creating keyspace... +Done. +Migrating database... +Done. +``` + +See the database schema using [cqlsh](https://cassandra.apache.org/doc/latest/cassandra/tools/cqlsh.html) in the container: + +```bash +docker exec -it carepet-scylla1 cqlsh +cqlsh> DESCRIBE KEYSPACES; + +carepet system_auth system_distributed_everywhere system_traces +system_schema system system_distributed + +cqlsh> USE carepet; +cqlsh:carepet> DESCRIBE TABLES; + +owner pet sensor sensor_avg measurement + +cqlsh:carepet> DESCRIBE TABLE pet; + +CREATE TABLE carepet.pet ( + owner_id uuid, + pet_id uuid, + address text, + age int, + name text, + weight float, + PRIMARY KEY (owner_id, pet_id) +) WITH CLUSTERING ORDER BY (pet_id ASC) + AND bloom_filter_fp_chance = 0.01 + AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'} + AND comment = '' + AND compaction = {'class': 'SizeTieredCompactionStrategy'} + AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'} + AND crc_check_chance = 1.0 + AND dclocal_read_repair_chance = 0.0 + AND default_time_to_live = 0 + AND gc_grace_seconds = 864000 + AND max_index_interval = 2048 + AND memtable_flush_period_in_ms = 0 + AND min_index_interval = 128 + AND read_repair_chance = 0.0 + AND speculative_retry = '99.0PERCENTILE'; + +cqlsh:carepet> exit; + + +``` + +At this point you have ScyllaDB running with the correct keyspace and tables. + +## Generate and ingest IoT data +Start ingesting IoT data (it's suggested to do this in a new separate terminal +because this process runs indefinitely). Make sure you're still in the virtual +environment: +```bash +source env/bin/activate +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +python src/sensor.py -h $NODE1 --measure 2 --buffer-interval 10 + +Welcome to the Pet collar simulator +New owner # 1cfbc0e5-6b05-476d-b170-2660cf40c02a +New pet # 1a0800ee-7643-4794-af7b-2ecaaf7078fc +New sensor(0) # b6155934-bd4e-47de-8649-1fad447aa036 +New sensor(1) # d2c62c4d-9621-469d-b62c-41ef2271fca7 +sensor # b6155934-bd4e-47de-8649-1fad447aa036 type T, new measure: 100.55118431400851, ts: 2023-01-08 17:36:17.126374 +sensor # d2c62c4d-9621-469d-b62c-41ef2271fca7 type L, new measure: 37.486651732296835, ts: 2023-01-08 17:36:17.126516 +``` + +This command starts a script that generates and ingests random IoT data coming +from two sensors every other second and inserts the data in batches +every ten seconds. Whenever you see `Pushing data` in the command line that is +when data actually gets insterted into ScyllaDB. + +Optional: You can modify the frequency of the generated data by changing the +`--measure` and `--buffer-interval` arguments. For example, +you can generate new data points every three seconds and insert the batches +every 30 seconds: +```bash +source env/bin/activate +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +python src/sensor.py -h $NODE1 --measure 3 --buffer-interval 30 +``` + +You can run multiple ingestion processes in parallel if you wish. + +## Set up and test REST API +In a new terminal, start running the API server (make sure that `port 8000` is free): +```bash +source env/bin/activate +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +python src/api.py -h $NODE1 + +INFO: Started server process [696274] +INFO: Waiting for application startup. +INFO: Application startup complete. +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +``` + +The API server is running on `http://127.0.0.1:8000`. Test with your +browser, or curl, if it works properly: +```bash +curl http://127.0.0.1:8000 + +{"message":"Pet collar simulator API"} +``` + +Next, you will test the following API endpoints: +* `/api/owner/{owner_id}` + + Returns all available data fields about the owner. +* `/api/owner/{owner_id}/pets` + + Returns the owner's pets. +* `/api/pet/{pet_id}/sensors` + + Returns all the sensors of a pet. + +To test these endpoints, you need to provide either an `owner_id` or a `pet_id` +as URL path parameter. You can get these values by copying them from the +beginning of output of the ingestion script: +```bash +source env/bin/activate +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +python src/sensor.py -h $NODE1 --measure 1 --buffer-interval 6 + +Welcome to the Pet collar simulator +New owner # 1cfbc0e5-6b05-476d-b170-2660cf40c02a <-- This is what you need! +New pet # 1a0800ee-7643-4794-af7b-2ecaaf7078fc <-- This is what you need! +New sensor(0) # b6155934-bd4e-47de-8649-1fad447aa036 +New sensor(1) # d2c62c4d-9621-469d-b62c-41ef2271fca7 +``` + +Copy the UUID values right after "New owner #" and "New pet #". A UUID value +looks like this: +``` +1cfbc0e5-6b05-476d-b170-2660cf40c02a +``` + +`/api/owner/{owner_id}` + +Paste the owner id from the terminal into the endpoint URL and open it with +your browser or use `curl`, for example: +```bash +curl http://127.0.0.1:8000/api/owner/4f42fb80-c209-4d19-8c43-daf554f1be23 + +{"owner_id":"4f42fb80-c209-4d19-8c43-daf554f1be23","address":"home","name":"Vito Russell"} +``` + +`/api/owner/{owner_id}/pets` + +Use the same owner id value to test this endpoint, for example: +```bash +curl http://127.0.0.1:8000/api/owner/4f42fb80-c209-4d19-8c43-daf554f1be23/pets + +[{"owner_id":"4f42fb80-c209-4d19-8c43-daf554f1be23","pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","address":"home","age":20,"name":"Duke","weight":14.41481876373291}] +``` + + `/api/pet/{pet_id}/sensors` + +Finally, use a pet id to test this endpoint, for example: +```bash +curl http://127.0.0.1:8000/api/pet/44f1624e-07c2-4971-85a5-85b9ad1ff142/sensors + +[{"pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","sensor_id":"4bb1d214-712b-453b-b53a-ac5d4df4a1f8","type":"T"},{"pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","sensor_id":"e81915d6-1155-45e4-9174-c58e4cb8cecf","type":"L"}] +``` + +## Resources + +* [ScyllaDB Python driver documentation](https://python-driver.docs.scylladb.com/stable/) +* [ScyllaDB Python driver on Github](https://github.com/scylladb/python-driver/) +* [ScyllaDB University: Coding with Python](https://university.scylladb.com/courses/the-mutant-monitoring-system-training-course/lessons/coding-with-python/) \ No newline at end of file diff --git a/stable/_sources/build-with-rust.md.txt b/stable/_sources/build-with-rust.md.txt new file mode 100644 index 00000000..3fa8c21c --- /dev/null +++ b/stable/_sources/build-with-rust.md.txt @@ -0,0 +1,438 @@ +# Build an IoT App with Rust + +## Architecture + +This section will walk through and explain the code for the different commands. +As explained in the Getting Started page, the project is structured as follow: + +- migrate (`/bin/migrate/main.rs`) - creates the `carepet` keyspace and tables +- collar (`/bin/sensor/main.rs`) - generates a pet health data and pushes it into the storage +- web app (`/main.rs`) - REST API service for tracking pets health state + +## Migrate + +Start by creating a local ScyllaDB cluster consisting of 3 nodes: + +```bash +docker-compose up -d +``` + +Docker-compose will spin up a ScyllaDB cluster consisting of 3 nodes (carepet-scylla1, carepet-scylla2 and carepet-scylla3) along with the app (for example go-app) container. Wait for about two minutes and check the status of the cluster: To check the status of the cluster: +```bash +docker exec -it carepet-scylla1 nodetool status +``` +Once all the nodes are in UN - Up Normal status, run the below commands: + +The below command allows you to get node IP address: + +```bash +docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1 +``` + +The run the following commands to execute the migrate main function. + +```bash +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +cargo run --bin migrate -- --hosts $NODE1 +``` + +The command executes the main function in the `bin/migrate/main.rs`. The function creates the keyspace and tables that you need to run the collar and server services. + +The below code in the `bin/migrate/main.rs` creates a new session then calls the `create_keyspace` , `migrate` functions. + +```rs +// migrate/main.rs + +async fn main() -> Result<()> { + care_pet::log::init(); + + let app = App::from_args(); + debug!("Configuration = {:?}", app); + + info!("Bootstrapping database..."); + + let sess = db::new_session(&app.db_config).await?; + + db::create_keyspace(&sess).await?; + db::migrate(&sess).await?; + + Ok(()) +} +``` + +The `new_session` function takes the config as a parameter and uses `SessionBuilder` class to crete a new session. + +```rs +// db/mod.rs + +pub async fn new_session(config: &Config) -> Result { + info!("Connecting to {}", config.hosts.join(", ")); + + SessionBuilder::new() + .known_nodes(&config.hosts) + .connection_timeout(config.timeout.into()) + .user( + config.username.clone().unwrap_or_default(), + config.password.clone().unwrap_or_default(), + ) + .build() + .await + .map_err(From::from) +} +``` + +For more information about creating a new session with the Rust Driver, please have a look at the [docs](https://rust-driver.docs.scylladb.com/stable/quickstart/example.html). + +`create_keyspace` function takes a session as an argument and creates a keyspace as defined in `db/keyspace.cql`: + +```cql +CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' }; +``` + +The CQL query above creates a new keyspace named carepet, with `NetworkTopologyStrategy` as replication strategy and a replication factor of 3. +More information about keyspace and replication on [Scylla University](https://university.scylladb.com/courses/data-modeling/lessons/basic-data-modeling-2/topic/keyspace/). + +Finally, `migrate` will execute the queries listed in `db/migrate.cql` to create the tables you need for the project. + +```cql +CREATE TABLE IF NOT EXISTS carepet.owner +( + owner_id UUID, + address TEXT, + name TEXT, + PRIMARY KEY (owner_id) +); + +... +``` + +You can check the database structure with: + +```bash +docker exec -it carepet-scylla1 cqlsh +cqlsh> USE carepet; +cqlsh:carepet> DESCRIBE TABLES +cqlsh:carepet> DESCRIBE TABLE pet +``` + +You should expect the following result: + +```cql +CREATE TABLE carepet.pet ( + owner_id uuid, + pet_id uuid, + chip_id text, + species text, + breed text, + color text, + gender text, + address text, + age int, + name text, + weight float, + PRIMARY KEY (owner_id, pet_id) +) WITH CLUSTERING ORDER BY (pet_id ASC) + AND bloom_filter_fp_chance = 0.01 + AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'} + AND comment = '' + AND compaction = {'class': 'SizeTieredCompactionStrategy'} + AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'} + AND crc_check_chance = 1.0 + AND dclocal_read_repair_chance = 0.1 + AND default_time_to_live = 0 + AND gc_grace_seconds = 864000 + AND max_index_interval = 2048 + AND memtable_flush_period_in_ms = 0 + AND min_index_interval = 128 + AND read_repair_chance = 0.0 + AND speculative_retry = '99.0PERCENTILE'; +``` + +## Sensor + +The sensor service simulates the collar's activity and periodically saves data to the database. Use the below commands to run the sensor service: + +```bash +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +cargo run --bin sensor -- --hosts $NODE1 --measure 5s --buffer-interval 1m +``` + +The above command executes `bin/sensor/main.rs` and and takes the following as arguments. + +- `hosts` : the IP address of the ScyllaDB node. +- `measure`: the interval between to sensor measures. +- `buffer-interval`: the interval between two database queries. + +```rs +// sensor/main.rs + +#[tokio::main] +async fn main() -> Result<()> { + care_pet::log::init(); + + let app = App::from_args(); + debug!("Configuration = {:?}", &app); + + info!("Welcome to the Pet collar simulator"); + + let sess = db::new_session_with_keyspace(&app.db_config).await?; + + let (owner, pet, sensors) = random_data(); + save_data(&sess, &owner, &pet, &sensors).await?; + run_sensor_data(&app, &sess, sensors).await?; + + Ok(()) +} +``` + +The `app` object contains the command's arguments listed above. +We then create a new session `sess` using `new_session_with_keyspace` function defined in `db/mod.rs`: + +```rs +// db/mod.rs + +pub async fn new_session_with_keyspace(config: &Config) -> Result { + let session = new_session(config).await?; + session.use_keyspace(KEYSPACE, true).await?; + Ok(session) +} +``` + +The `save_data` method connects to the datbase and saves random `owner`, `pet` and the `sensors` to the database using `insert_query` macro defined in `src/mod.rs`. + +```rs +// sensor/main.rs + +async fn save_data(sess: &Session, owner: &Owner, pet: &Pet, sensors: &[Sensor]) -> Result<()> { + sess.query(insert_query!(Owner), owner).await?; + info!("New owner # {}", owner.owner_id); + + sess.query(insert_query!(Pet), pet).await?; + info!("New pet # {}", pet.pet_id); + + for sensor in sensors { + sess.query(insert_query!(Sensor), sensor).await?; + } + + Ok(()) +} +``` + +The `run_sensor_data` generates random data and inserts it to the database every `buffer_interval`. + +```rs +async fn run_sensor_data(cfg: &App, sess: &Session, sensors: Vec) -> Result<()> { + let measure: time::Duration = cfg.measure.into(); + let buffer_interval: time::Duration = cfg.buffer_interval.into(); + + let mut last = Instant::now(); + loop { + let mut measures = vec![]; + while last.elapsed() < buffer_interval { + sleep(measure).await; + + for sensor in &sensors { + let measure = read_sensor_data(sensor); + info!( + "sensor # {} type {} new measure {} ts {}", + sensor.sensor_id, + sensor.r#type.as_str(), + &measure.value, + measure.ts.format_rfc3339(), + ); + + measures.push(measure); + } + } + + last = last + + time::Duration::from_nanos( + (measure.as_nanos() * (last.elapsed().as_nanos() / measure.as_nanos())) as u64, + ); + + info!("Pushing data"); + + let batch = measures.iter().fold(Batch::default(), |mut batch, _| { + batch.append_statement(insert_query!(Measure)); + batch + }); + + sess.batch(&batch, measures) + .await + .map_err(|err| error!("execute batch query {:?}", err)) + .ok(); + } +} +``` + +## Server + +The server service is a REST API for tracking the pets’ health state. The service was built using [Rocket](https://rocket.rs) and allows users to query the database via HTTP. + +Run the following commands to start the server: + +```bash +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1) +cargo run -- --hosts $NODE1 +``` + +The `src/main.rs` main function mounts the api on `/api` and defines the routes. + +```rs +// src/main.rs + +#[rocket::main] +async fn main() -> Result<()> { + care_pet::log::init(); + + let app = App::from_args(); + if app.verbose { + info!("Configuration = {:?}", app); + } + + let sess = db::new_session_with_keyspace(&app.db_config).await?; + + rocket::build() + .mount( + "/api", + routes![ + handler::measures::find_sensor_data_by_sensor_id_and_time_range, + handler::owner::find_owner_by_id, + handler::pets::find_pets_by_owner_id, + handler::sensors::find_sensors_by_pet_id, + handler::avg::find_sensor_avg_by_sensor_id_and_day + ], + ) + .manage(sess) + .launch() + .await + .map_err(From::from) +} +``` + +The handlers can be found in the `src/handler` folder for each route. + +Let's have a look at `handler/mesure.rs` file: + +```rs +#[get("/sensor//values?&")] +pub async fn find_sensor_data_by_sensor_id_and_time_range( + session: &State, + id: UuidParam, + from: DateTimeParam, + to: DateTimeParam, +) -> Result>, JsonError> { + let rows = session + .query( + format!( + "SELECT {} FROM {} WHERE {} = ? and {} >= ? and {} <= ?", + Measure::FIELD_NAMES.value, + Measure::table(), + Measure::FIELD_NAMES.sensor_id, + Measure::FIELD_NAMES.ts, + Measure::FIELD_NAMES.ts, + ), + (id.0, from.0, to.0), + ) + .await + .map_err(|err| json_err(Status::InternalServerError, err))? + .rows + .unwrap_or_default() + .into_typed::<(f32,)>(); + + let values = rows + .map(|v| v.map(|v| v.0)) + .collect::, _>>() + .map_err(|err| json_err(Status::InternalServerError, err))?; + + Ok(Json(values)) +} +``` + +The GET request on URL `/sensor//values?&` triggers `find_sensor_data_by_sensor_id_and_time_range` function. + +`find_sensor_data_by_sensor_id_and_time_range` takes `session`, `id`, `from` and `to` as params. The function runs a `SELECT` query then returns `rows`. + +## Retrieving informations from API + +To test out the API in your terminal, use the following command to retrieve informations of a specific pet owner: + +```bash +curl http://127.0.0.1:8000/owner/{id} +``` + +> If you don't have an owner_id, run the `sensor` command and it will generate users and pets on your terminal. + +and you should receive a response similar to this: + +```json +{ + "owner_id": "5b5a7b4d-a2c0-48b0-91e1-de6a5b37c923", + "address": "home", + "name": "sedtdkaa" +} +``` + + +If you want to list owner's pets you can use the following command: + +```shell +curl http://127.0.0.1:8000/owner/{id}/pets +``` + +and you should receive a response similar to this: + +```json +[ + { + "owner_id": "5b5a7b4d-a2c0-48b0-91e1-de6a5b37c923", + "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999", + "chip_id": null, + "species": "dog", + "breed": "golden-retriever", + "color": "black", + "gender": "M", + "age": 4, + "weight": 9.523097, + "address": "awesome-address", + "name": "doggo" + } +] +``` + +If you want to list the active pet sensors you can use the following command: + +```shell +curl http://127.0.0.1:8000/pet/{pet_id}/sensors +``` + +and you should receive a response similar to this: + +```json +[ + { + "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999", + "sensor_id": "7a8b3831-0512-4501-90f2-700c7133aeed", + "type": "T" + }, + { + "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999", + "sensor_id": "81250bab-cf1c-4c7a-84f1-b291a0f325ef", + "type": "P" + }, + { + "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999", + "sensor_id": "a22a2fdb-4aad-4abe-b0d9-381aa07a26af", + "type": "L" + } +] +``` + + +## Resources + +* [ScyllaDB Rust driver documentation](https://rust-driver.docs.scylladb.com/stable/) +* [ScyllaDB Rust code examples](https://github.com/scylladb/scylla-rust-driver/tree/main/examples) +* [ScyllaDB Rust driver on Github](https://github.com/scylladb/scylla-rust-driver) +* [ScyllaDB University: Getting Started with Rust](https://university.scylladb.com/courses/using-scylla-drivers/lessons/rust-and-scylla-2/) + diff --git a/stable/_sources/deploy-in-cloud.md.txt b/stable/_sources/deploy-in-cloud.md.txt new file mode 100644 index 00000000..314ff2a6 --- /dev/null +++ b/stable/_sources/deploy-in-cloud.md.txt @@ -0,0 +1,71 @@ +# Deploy in ScyllaDB Cloud with Terraform + +ScyllaDB Cloud has a [Terraform provider](https://github.com/scylladb/terraform-provider-scylladbcloud) which means that you can spin up new +ScyllaDB Cloud clusters easily using Terraform. Follow the instructions below to +set up the care-pet sample application in a ScyllaDB Cloud environment using Terraform. + +You'll set up Terraform to: +1. Create a new ScyllaDB Cloud cluster (you need a [ScyllaDB Cloud account](https://cloud.scylladb.com/account/sign-up)) +1. Execute a CQL file that creates a new keyspace and tables for the care-pet project + +## Prerequisites +* [Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) +* [Python](https://www.python.org/downloads/) +* [ScyllaDB Cloud API token](https://cloud.docs.scylladb.com/stable/api-docs/api-get-started.html) + +## Get started + +### Clone the repository +Clone the repository if you haven't already: +```bash +git clone https://github.com/scylladb/care-pet.git +``` + +### Install CQLSH +Install the standalone CQLSH Python package: +```bash +pip install cqlsh +``` + +This package will be used to connect to ScyllaDB and create the initial schema. + +### Spin up a new ScyllaDB Cloud cluster +Go to the `terraform` directory and run `terraform init` +```bash +cd terraform/ +terraform init +``` + +Apply the changes that are configured in the `main.tf` file: +```bash +terraform apply +``` + +You'll be asked to provide your ScyllaDB Cloud API token (more info [in docs](https://cloud.docs.scylladb.com/stable/api-docs/api-get-started.html)): +```bash +var.scylla_api_token + Your own ScyllaDB Cloud API token + + Enter a value: +``` + +You'll also be asked if you want to perform the actions configured in Terraform, just type `yes`: +```bash +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. + + Enter a value: yes + + scylladbcloud_cluster.care_pet: Creating... +``` + +Spinning up the cluster takes about ~10 minutes. While the process is underway, you can go to your +ScyllaDB [Cloud dashboard](https://cloud.scylladb.com/clusters/list) and verify that the cluster is getting set up: + +![cluster setting up](../terraform/cloud_screen.png) + +After the process is completed, go to the "Connect" tab in in the cloud console +and connect to your newly created cluster with your favourite tool. + + diff --git a/stable/_sources/design-and-data-model.md.txt b/stable/_sources/design-and-data-model.md.txt new file mode 100644 index 00000000..a425bc41 --- /dev/null +++ b/stable/_sources/design-and-data-model.md.txt @@ -0,0 +1,165 @@ +# Design and Data Model + +You can learn more about Data Modeling in Scylla (and NoSQL) by taking +[this course](https://university.scylladb.com/courses/data-modeling/) on Scylla +University. The main goal of data modeling in Scylla is to perform queries fast, +even if we sometimes have to duplicate data. + +Let's build our schema around the queries we are going to run against our domain +entities. When creating the data model, you need to consider both the conceptual +data model and the application workflow: which queries will be performed by +which users and how often. + +To achieve that, we want: + +- Even data distribution +- To minimize the number of partitions accessed in a read query. + +On the other hand, our focus won't be on avoiding data duplication or minimizing +the number of writes. You're probably familiar with the steps defined here: + +![](https://lh5.googleusercontent.com/5JqE89v8KJbSuVsnGswHn83sJOV-tjpeH6r1fqdNl6S77ncqAYb3kIZPSgNI8bqN_43OyZNbHQVpXdqMBFrRmsEvG3JORR302EhMnIb9qa6nuNL7cP2JJDZ4Uon_Pp-QmSCoEQ) + +## Conceptual Data Model + +Starting with the conceptual data model, we need to identify the key entities +and the relationships between them. Our application has pets. Each dog can be +tracked by many followers (typically the owners). A follower can also track more +than one dog. Each dog can have a few sensors. Each sensor takes measurements: + +![](https://lh3.googleusercontent.com/GrFS0HY7XgABabCEp5Fbc0dULsujHkvSykFMiMZRI5TjJTYrzckVCJ29L4BgnEqc8dB7t1_VzsRsJCJjwiNI8xHdQ0tGh9qZptZfRsq7gDXHVogwfJG8Y_DIEJrgLX40zjvV5w) + +## Application Workflow + +Next, we move on to the Application Workflow. In this part, we identify the main +queries or what questions we will ask the database. This part is important in +Scylla, and other NoSQL databases and, as opposed to relational databases is +performed early on in the data modeling process. Remember that our data modeling +is built around the queries. + +![](https://lh5.googleusercontent.com/bHN-aBIt-cJ-77s5AWn6Dt0djC-gLQRSArF6b56s3mxpzx-0oG3TgXYOJzTOwrhUUdT0WcEZPTTTdk8B4aY2fbGMgs044DKxwPMC1ATrphI4GBRS8rcVboWpjlg5cO4JRcTZxQ) + +## Queries + +Now we can detail the above queries in +[CQL](https://university.scylladb.com/courses/data-modeling/lessons/basic-data-modeling-2/topic/cql-cqlsh-and-basic-cql-syntax/): + +Q1: Find a Follower with a specific ID + + SELECT * FROM owner WHERE owner_id = ? + +Q2: Find the pets that the follower tracks + + SELECT * FROM pet WHERE owner_id = ? + +Q3: Find the sensors of a pet + + SELECT * FROM sensor WHERE pet_id = ? + +Q4: Find the measurements for a sensor in a date range + + SELECT * FROM measurements WHERE sensor_id = ? AND ts <= ? and ts >= ?; + +Q5: Find a daily summary of hour based aggregates + + SELECT * FROM sensor_avg WHERE sensor_id = ? AND date = ? ORDER BY date ASC, hour ASC; + +## Logical Data Model + +Using the outcomes of the application workflow and the conceptual data model, we +can now create the logical data model. At this stage, we determine how our +tables will look and which fields will be used as primary and clustering keys. +Selecting a primary key and clustering key is highly important, you can learn +more about it in +[this lesson](https://university.scylladb.com/courses/data-modeling/lessons/basic-data-modeling-2/). +Remember that in Scylla, it's better to duplicate data than to join, see more +about denormalization in +[this lesson](https://university.scylladb.com/courses/data-modeling/lessons/advanced-data-modeling/topic/denormalization/). + +![](https://lh4.googleusercontent.com/zF8v3divX_VsG5z7pOmGOtdLj7_7AVrembG6ep630WsVqJXKMthEoMyPAkfaJsU7a-np9fO84lmfbcHkPv-dX-_45Aczafnm4V7OroHgt0Kd6Ao7vLF6eK_m-d6X5TJcnylpow) + +## Physical Data Model  + +In this part, we take the Logical Data Model above and add CQL data types. Make +sure you're familiar with the ScyllaDB (and Cassandra for that matter) +[data types](https://university.scylladb.com/courses/data-modeling/lessons/advanced-data-modeling/topic/common-data-types-and-collections/) +before proceeding. + +Based on the high availability requirements, we will use a +[replication factor](https://university.scylladb.com/courses/scylla-essentials-overview/lessons/high-availability/topic/fault-tolerance-replication-factor/) +(RF) of three. The RF is defined when we create the +[Keyspace](https://university.scylladb.com/courses/data-modeling/lessons/basic-data-modeling-2/topic/keyspace/), +as we will see later on. Choosing the compaction strategy is explained +[here](https://docs.scylladb.com/architecture/compaction/compaction-strategies/) +and in [this](https://university.scylladb.com/courses/scylla-operations/lessons/compaction-strategies/) +University Lesson. For the tables sensor_avg and measurement, we will use the +[Time Window Compaction Strategy (TWCS)](https://docs.scylladb.com/getting-started/compaction/#time-window-compactionstrategy-twcs). + +The reason is those tables contain time-series data. The "measurement" table +stores sensor measurements, and the "sensor_avg" stores aggregated hourly +averages. For such data, there is an optimized compaction strategy TWCS based on +the Size Tiered Compaction Strategy with the fair assumption that the data at +different time slots will never overlap. That isolates buckets compaction +in-between the time windows into independent units reducing overall compaction +write amplification. For the other tables, we will use the default +[compaction strategy](https://university.scylladb.com/courses/scylla-operations/lessons/compaction-strategies/), +[Size Tiered Compaction Strategy (STCS)](https://university.scylladb.com/courses/scylla-operations/lessons/compaction-strategies/topic/size-tiered-and-leveled-compaction-strategies-stcs-lcs/). +Remember that if you are using [Scylla Enterprise](https://www.scylladb.com/product/scylla-enterprise/), you should +probably be using [Incremental Compaction Strategy (ICS)](https://university.scylladb.com/courses/scylla-operations/lessons/compaction-strategies/topic/incremental-compaction-strategy-ics/) +as it offers better performance. We can now define the tables below, according +to the physical data model. + + CREATE TABLE IF NOT EXISTS owner ( +     owner_id UUID, +     address TEXT, +     name    TEXT, +     PRIMARY KEY (owner_id) + ); + + CREATE TABLE IF NOT EXISTS pet ( +     owner_id UUID, +     pet_id   UUID, + chip_id TEXT, + species TEXT, + breed TEXT, + color TEXT, + gender TEXT, +     age     INT, +     weight  FLOAT, +     address TEXT, +     name    TEXT, +     PRIMARY KEY (owner_id, pet_id) + ); + + CREATE TABLE IF NOT EXISTS sensor ( +     pet_id UUID, +     sensor_id UUID, +     type TEXT, +     PRIMARY KEY (pet_id, sensor_id) + ); + + CREATE TABLE IF NOT EXISTS measurement ( +     sensor_id UUID, +     ts       TIMESTAMP, +     value    FLOAT, +     PRIMARY KEY (sensor_id, ts) + ) WITH compaction = { 'class' : 'TimeWindowCompactionStrategy' }; + + CREATE TABLE IF NOT EXISTS sensor_avg ( +     sensor_id UUID, +     date    DATE, +     hour    INT, +     value   FLOAT, +     PRIMARY KEY (sensor_id, date, hour) + ) WITH compaction = { 'class' : 'TimeWindowCompactionStrategy' }; + +Some more advanced topics not covered in this guide are +[Collections](https://university.scylladb.com/courses/data-modeling/lessons/advanced-data-modeling/topic/common-data-types-and-collections/), +User-Defined[Types](https://university.scylladb.com/courses/data-modeling/lessons/advanced-data-modeling/topic/user-defined-types-udt/) +(UDT), expiring data with [time to live (TTL)](https://university.scylladb.com/courses/data-modeling/lessons/advanced-data-modeling/topic/expiring-data-with-ttl-time-to-live/), +and [Counters](https://university.scylladb.com/courses/data-modeling/lessons/advanced-data-modeling/topic/counters/). + +To summarize, when data modeling with Scylla, we have to know our data, think +about our queries, pay attention to the primary key and clustering key +selection, and not be afraid to duplicate data. + diff --git a/stable/_sources/getting-started.md.txt b/stable/_sources/getting-started.md.txt new file mode 100644 index 00000000..2d1dfc82 --- /dev/null +++ b/stable/_sources/getting-started.md.txt @@ -0,0 +1,117 @@ +# Getting Started with CarePet: A sample IoT App + +## Introduction + +This guide will show you how to create an IoT app from scratch and configure it +to use Scylla as the backend datastore. It'll walk you through all the stages +of the development process, from gathering requirements to building and running +the application. + +As an example, you will use an application called CarePet. CarePet allows pet +owners to track their pets' health by monitoring their key health parameters, +such as temperature or pulse. The application consists of three parts: +- A pet collar with sensors that collects pet health data and sends the data to the datastore. +- A web app for reading the data and analyzing the pets' health. +- A database migration module. + +You can use this example with minimal changes for any IoT application.  + +## Architecture + +- `migrate` - Creates the CarePet keyspace and tables. +- `sensor` - Generates pet health data and pushes it into storage. +- `server` - REST API service for tracking the pets' health state. + +![Build your first ScyllaDB Powered App - Raouf](https://user-images.githubusercontent.com/13738772/158378310-11a39630-b390-4df0-8096-2c1751e56570.jpg) + + +## Requirements + +### Prerequisites for Deploying the Application + +The example application uses Docker to run a three-node ScyllaDB cluster. You can also use Scylla Cloud as your database. +Claim your free Scylla Cloud account [here](https://scylladb.com/cloud). + +### Use Case Requirements + +Each pet collar has sensors that report four different measurements: +temperature, pulse, location, and respiration. + +The collar reads the measurements from the sensors once per second +and sends the data directly to the app. + +### Performance Requirements + +The application has two performance-related parts: sensors that write to +the database (throughput sensitive) and a backend dashboard that reads from +the database (latency sensitive). + +* This example assumes 99% writes (sensors) and 1% reads (backend dashboard). +* SLA: + - Writes: throughput of 100K operations per second. + - Reads: latency of up to 10 milliseconds for the + [99th percentile](https://engineering.linkedin.com/performance/who-moved-my-99th-percentile-latency). +* The application requires high availability and fault tolerance. Even if a +ScyllaDB node goes down or becomes unavailable, the cluster is expected to +remain available and continue to provide service. You can learn more about +Scylla high availability in [this lesson](https://university.scylladb.com/courses/scylla-essentials-overview/lessons/high-availability/). + + +## Deploying the Application in ScyllaDB Cloud + +Using the ScyllaDB Cloud [Terraform provider](https://registry.terraform.io/providers/scylladb/scylladbcloud/latest/docs), you can easily spin up new ScyllaDB Cloud clusters. Complete this tutorial quicker by creating a new `t3.micro` cluster (the smallest instance) in ScyllaDB Cloud. Go to [Deploy in ScyllaDB Cloud with Terraform](/deploy-in-cloud.md) for instructions. + +## Deploying the Application Locally + +1. Check out the care-pet repository from GitHub and go to the directory of + the language you want to use (Go, Java, etc.): + + ``` + git clone git@github.com:scylladb/care-pet.git + cd care-pet/go + ``` + +1. Create a local ScyllaDB cluster consisting of three nodes: + + ``` + docker-compose up -d + ``` + + Docker-compose will spin up a ScyllaDB cluster consisting of three nodes: + carepet-scylla1, carepet-scylla2 and carepet-scylla3. The process will + take about two minutes. + +1. Check the status of the cluster: + + ``` + docker exec -it carepet-scylla1 nodetool status + ``` + +1. Continue by following the instructions for the programming language you're using. See [Build the Application with Your Programming Language](#build-the-application-with-your-programming-language). + +(build-the-application-with-your-programming-language)= +## Build the Application with Your Programming Language + +- [Build with Go](/build-with-go.md) +- [Build with Java](/build-with-java.md) +- [Build with JavaScript](/build-with-javascript.md) +- [Build with PHP](/build-with-php.md) +- [Build with Rust](/build-with-rust.md) +- [Build with Python](/build-with-python.md) + + +## Additional Resources + +- [Scylla Essentials](https://university.scylladb.com/courses/scylla-essentials-overview/) course on Scylla University. It provides an introduction to Scylla and explains the basics. +- [Data Modeling and Application Development](https://university.scylladb.com/courses/data-modeling/) course on Scylla University. It explains basic and advanced data modeling techniques, including information on workflow application, query analysis, denormalization, and other NoSQL data modeling topics. +- [Scylla Documentation](https://docs.scylladb.com/) +- Scylla users [slack channel](http://slack.scylladb.com/) + +Future Work + +- Add Sizing +- Add Benchmarking +- Add Python implementation +- In a real-world application, it would be better to aggregate data in an internal buffer and send it once a day to the application gateway in a batch, implying techniques such as delta encoding. It could also aggregate data at a lower resolution and take measurements less frequently. The collar could notify the pet's owner about suspicious health parameters directly or via the application.  +- Add location tracking info to send alerts when the pet enters/leaves safe zones using known WiFi networks. +- Use the measurements to present to the pet owner health alerts, vital signs, sleeping levels, activity levels, and calories burned. diff --git a/stable/_sources/index.rst.txt b/stable/_sources/index.rst.txt new file mode 100644 index 00000000..9f9a9c68 --- /dev/null +++ b/stable/_sources/index.rst.txt @@ -0,0 +1,124 @@ +:full-width: +:hide-sidebar: +:hide-secondary-sidebar: +:hide-version-warning: +:hide-pre-content: +:hide-post-content: +:landing: + +.. title:: Scylla Care-Pet Example + +.. hero-box:: + :title: Build a low latency IoT project with a Real-Time NoSQL Database + :image: /_static/img/mascots/scylla-care-pet-mascot.svg + :button_icon: fa fa-github + :button_url: https://github.com/scylladb/care-pet + :button_text: Care-Pet Project + + This tutorial is a step-by-step guide to build an IoT project connected to Scylla Cloud. + After completing the project, you will be able to create back-end services that share data through a Scylla Cloud cluster. + +.. raw:: html + +
      + +.. raw:: html + +
      + +
      + + +.. topic-box:: + :title: Getting Started with Care-Pet + :link: getting-started + :icon: scylla-icon scylla-icon--getting-started + :class: large-4 + :anchor: Get Started + + Create an IoT app from scratch and configure it to use ScyllaDB as the backend datastore. + +.. topic-box:: + :title: Design and Data Model + :link: design-and-data-model + :icon: scylla-icon scylla-icon--overview + :class: large-4 + :anchor: Learn more + + Learn more about the queries used in the example, make the primary key and clustering key selection, and create the database schema. + +.. topic-box:: + :title: Care-Pet Blog + :icon: scylla-icon scylla-icon--blog + :link: https://www.scylladb.com/2020/09/09/carepet-an-example-iot-use-case-for-hands-on-app-developers/ + :class: large-4,small-12 + :anchor: Read the article + + The Care-Pet Example blog walks you through the example and adds additional information. + +.. topic-box:: + :title: Terraform integration + :icon: scylla-icon scylla-icon--cloud + :link: deploy-in-cloud + :class: large-12 + :anchor: Deploy in the cloud + + Spin up a new ScyllaDB Cloud cluster with Terraform and get started with this example in a cloud environment. + +.. topic-box:: + :title: Build with Go + :image: /_static/img/programming_languages/go-lang.png + :link: build-with-go + :class: large-4 + +.. topic-box:: + :title: Build with Java + :image: /_static/img/programming_languages/java.png + :link: build-with-java + :class: large-4 + +.. topic-box:: + :title: Build with Rust + :image: /_static/img/programming_languages/rust.png + :link: build-with-rust + :class: large-4 + +.. topic-box:: + :title: Build with JavaScript + :image: /_static/img/programming_languages/javascript.png + :link: build-with-javascript + :class: large-4 + +.. topic-box:: + :title: Build with Python + :image: /_static/img/programming_languages/python.png + :link: build-with-python + :class: large-4 + +.. topic-box:: + :title: Build with PHP + :image: /_static/img/programming_languages/php.png + :link: build-with-php + :class: large-4 + +.. raw:: html + +
      + +.. toctree:: + :maxdepth: 3 + :hidden: + + Getting Started with CarePet: A sample IoT App + Deploy in cloud + Design and Data Model + Build with Go + Build with JavaScript + Build with Java + Build with Python + Build with PHP + Build with Rust + Care-Pet GitHub Repository + Care-Pet Blog + + diff --git a/stable/_static/basic.css b/stable/_static/basic.css new file mode 100644 index 00000000..30fee9d0 --- /dev/null +++ b/stable/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/stable/_static/check-solid.svg b/stable/_static/check-solid.svg new file mode 100644 index 00000000..92fad4b5 --- /dev/null +++ b/stable/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/stable/_static/clipboard.min.js b/stable/_static/clipboard.min.js new file mode 100644 index 00000000..54b3c463 --- /dev/null +++ b/stable/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/stable/_static/copybutton.css b/stable/_static/copybutton.css new file mode 100644 index 00000000..f1916ec7 --- /dev/null +++ b/stable/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

      Short

      + */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/stable/_static/copybutton.js b/stable/_static/copybutton.js new file mode 100644 index 00000000..2ea7ff3e --- /dev/null +++ b/stable/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/stable/_static/copybutton_funcs.js b/stable/_static/copybutton_funcs.js new file mode 100644 index 00000000..dbe1aaad --- /dev/null +++ b/stable/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/stable/_static/css/main.css b/stable/_static/css/main.css new file mode 100644 index 00000000..65eb0a55 --- /dev/null +++ b/stable/_static/css/main.css @@ -0,0 +1 @@ +@media print,screen and (min-width:40em){.reveal,.reveal.large,.reveal.small,.reveal.tiny{left:auto;margin:0 auto;right:auto}}/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */html{-webkit-text-size-adjust:100%;line-height:1.15}h1{font-size:2em;margin:.67em 0}hr{-webkit-box-sizing:content-box;box-sizing:content-box;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:0;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}[data-whatinput=mouse] *,[data-whatinput=mouse] :focus,[data-whatinput=touch] *,[data-whatinput=touch] :focus,[data-whatintent=mouse] *,[data-whatintent=mouse] :focus,[data-whatintent=touch] *,[data-whatintent=touch] :focus{outline:0}[draggable=false]{-webkit-touch-callout:none;-webkit-user-select:none}.foundation-mq{font-family:"small=0em&medium=40em&large=64em&xlarge=75em&xxlarge=90em"}html{-webkit-box-sizing:border-box;font-size:100%}*,:after,:before{-webkit-box-sizing:inherit}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:#fefefe;color:#0a0a0a;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;line-height:1.5;margin:0;padding:0}img{-ms-interpolation-mode:bicubic;display:inline-block;height:auto;vertical-align:middle}textarea{border-radius:0;height:auto;min-height:50px}select{-webkit-box-sizing:border-box;box-sizing:border-box;width:100%}.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:0 0;border:0;border-radius:0;cursor:auto;line-height:1;padding:0}[data-whatinput=mouse] button{outline:0}pre{-webkit-overflow-scrolling:touch;overflow:auto}button,input,optgroup,select,textarea{font-family:inherit}.is-visible{display:block!important}.is-hidden{display:none!important}[type=color],[type=date],[type=datetime-local],[type=datetime],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fefefe;border:1px solid #cacaca;border-radius:0;-webkit-box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);box-shadow:inset 0 1px 2px hsla(0,0%,4%,.1);-webkit-box-sizing:border-box;box-sizing:border-box;color:#0a0a0a;display:block;font-family:inherit;font-size:1rem;font-weight:400;height:2.4375rem;line-height:1.5;margin:0 0 1rem;padding:.5rem;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s;width:100%}[type=color]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=datetime]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,textarea:focus{background-color:#fefefe;border:1px solid #8a8a8a;-webkit-box-shadow:0 0 5px #cacaca;box-shadow:0 0 5px #cacaca;outline:0;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}textarea{max-width:100%}textarea[rows]{height:auto}input:disabled,input[readonly],textarea:disabled,textarea[readonly]{background-color:#e6e6e6;cursor:not-allowed}[type=button],[type=submit]{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}input[type=search]{-webkit-box-sizing:border-box;box-sizing:border-box}::-webkit-input-placeholder{color:#cacaca}::-moz-placeholder{color:#cacaca}:-ms-input-placeholder{color:#cacaca}::-ms-input-placeholder{color:#cacaca}::placeholder{color:#cacaca}[type=checkbox],[type=file],[type=radio]{margin:0 0 1rem}[type=checkbox]+label,[type=radio]+label{display:inline-block;margin-bottom:0;margin-left:.5rem;margin-right:1rem;vertical-align:baseline}[type=checkbox]+label[for],[type=radio]+label[for]{cursor:pointer}label>[type=checkbox],label>[type=radio]{margin-right:.5rem}[type=file]{width:100%}label{color:#0a0a0a;display:block;font-size:.875rem;font-weight:400;line-height:1.8;margin:0}label.middle{line-height:1.5;margin:0 0 1rem;padding:.5625rem 0}.help-text{color:#0a0a0a;font-size:.8125rem;font-style:italic;margin-top:-.5rem}.input-group{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-bottom:1rem;width:100%}.input-group>:first-child,.input-group>:first-child.input-group-button>*,.input-group>:last-child,.input-group>:last-child.input-group-button>*{border-radius:0}.input-group-button,.input-group-button a,.input-group-button button,.input-group-button input,.input-group-button label,.input-group-field,.input-group-label{margin:0;white-space:nowrap}.input-group-label{-webkit-box-flex:0;-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;background:#e6e6e6;border:1px solid #cacaca;color:#0a0a0a;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;padding:0 1rem;text-align:center;white-space:nowrap}.input-group-label:first-child{border-right:0}.input-group-label:last-child{border-left:0}.input-group-field{-webkit-box-flex:1;border-radius:0;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px;min-width:0}.input-group-button{-webkit-box-flex:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;padding-bottom:0;padding-top:0;text-align:center}.input-group-button a,.input-group-button button,.input-group-button input,.input-group-button label{-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;font-size:1rem;height:auto;padding-bottom:0;padding-top:0}fieldset{border:0;margin:0;padding:0}legend{margin-bottom:.5rem;max-width:100%}.fieldset{border:1px solid #cacaca;margin:1.125rem 0;padding:1.25rem}.fieldset legend{margin:0 0 0 -.1875rem;padding:0 .1875rem}select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fefefe;background-image:url('data:image/svg+xml;utf8,');background-origin:content-box;background-position:right -1rem center;background-repeat:no-repeat;background-size:9px 6px;border:1px solid #cacaca;border-radius:0;color:#0a0a0a;font-family:inherit;font-size:1rem;font-weight:400;height:2.4375rem;line-height:1.5;margin:0 0 1rem;padding:.5rem 1.5rem .5rem .5rem;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}@media screen and (min-width:0\0){select{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==)}}select:focus{background-color:#fefefe;border:1px solid #8a8a8a;-webkit-box-shadow:0 0 5px #cacaca;box-shadow:0 0 5px #cacaca;outline:0;-webkit-transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:border-color .25s ease-in-out,-webkit-box-shadow .5s;transition:box-shadow .5s,border-color .25s ease-in-out;transition:box-shadow .5s,border-color .25s ease-in-out,-webkit-box-shadow .5s}select:disabled{background-color:#e6e6e6;cursor:not-allowed}select::-ms-expand{display:none}select[multiple]{background-image:none;height:auto}select:not([multiple]){padding-bottom:0;padding-top:0}.is-invalid-input:not(:focus){background-color:#f9ecea;border-color:#cc4b37}.is-invalid-input:not(:focus)::-webkit-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus)::-moz-placeholder{color:#cc4b37}.is-invalid-input:not(:focus):-ms-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus)::-ms-input-placeholder{color:#cc4b37}.is-invalid-input:not(:focus)::placeholder{color:#cc4b37}.form-error,.is-invalid-label{color:#cc4b37}.form-error{display:none;font-size:.75rem;font-weight:700;margin-bottom:1rem;margin-top:-.5rem}.form-error.is-visible{display:block}blockquote,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,li,ol,p,pre,td,th,ul{margin:0;padding:0}p{font-size:inherit;line-height:1.6;margin-bottom:1rem;text-rendering:optimizeLegibility}em,i{font-style:italic}b,em,i,strong{line-height:inherit}b,strong{font-weight:700}small{font-size:80%;line-height:inherit}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{color:inherit;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-style:normal;font-weight:400;text-rendering:optimizeLegibility}.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#cacaca;line-height:0}.h1,h1{font-size:1.5rem}.h1,.h2,h1,h2{line-height:1.4;margin-bottom:.5rem;margin-top:0}.h2,h2{font-size:1.25rem}.h3,h3{font-size:1.1875rem}.h3,.h4,h3,h4{line-height:1.4;margin-bottom:.5rem;margin-top:0}.h4,h4{font-size:1.125rem}.h5,h5{font-size:1.0625rem}.h5,.h6,h5,h6{line-height:1.4;margin-bottom:.5rem;margin-top:0}.h6,h6{font-size:1rem}@media print,screen and (min-width:40em){.h1,h1{font-size:3rem}.h2,h2{font-size:2.5rem}.h3,h3{font-size:1.9375rem}.h4,h4{font-size:1.5625rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}}a{color:#1779ba;cursor:pointer;line-height:inherit;text-decoration:none}a:focus,a:hover{color:#1468a0}a img,hr{border:0}hr{border-bottom:1px solid #cacaca;clear:both;height:0;margin:1.25rem auto;max-width:75rem}dl,ol,ul{line-height:1.6;list-style-position:outside;margin-bottom:1rem}li{font-size:inherit}ul{list-style-type:disc}ol,ul{margin-left:1.25rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0;margin-left:1.25rem}dl{margin-bottom:1rem}dl dt{font-weight:700;margin-bottom:.3rem}blockquote{border-left:1px solid #cacaca;margin:0 0 1rem;padding:.5625rem 1.25rem 0 1.1875rem}blockquote,blockquote p{color:#8a8a8a;line-height:1.6}abbr,abbr[title]{border-bottom:1px dotted #0a0a0a;cursor:help;text-decoration:none}figure,kbd{margin:0}kbd{background-color:#e6e6e6;color:#0a0a0a;font-family:Consolas,Liberation Mono,Courier,monospace;padding:.125rem .25rem 0}.subheader{color:#8a8a8a;font-weight:400;line-height:1.4;margin-bottom:.5rem;margin-top:.2rem}.lead{font-size:125%;line-height:1.6}.stat{font-size:2.5rem;line-height:1}p+.stat{margin-top:-1rem}ol.no-bullet,ul.no-bullet{list-style:none;margin-left:0}.cite-block,cite{color:#8a8a8a;display:block;font-size:.8125rem}.cite-block:before,cite:before{content:"— "}.code-inline,code{word-wrap:break-word;display:inline;max-width:100%;padding:.125rem .3125rem .0625rem}.code-block,.code-inline,code{background-color:#e6e6e6;border:1px solid #cacaca;color:#0a0a0a;font-family:Consolas,Liberation Mono,Courier,monospace;font-weight:400}.code-block{display:block;margin-bottom:1.5rem;overflow:auto;padding:1rem;white-space:pre}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}@media print,screen and (min-width:40em){.medium-text-left{text-align:left}.medium-text-right{text-align:right}.medium-text-center{text-align:center}.medium-text-justify{text-align:justify}}@media print,screen and (min-width:64em){.large-text-left{text-align:left}.large-text-right{text-align:right}.large-text-center{text-align:center}.large-text-justify{text-align:justify}}.show-for-print{display:none!important}@media print{*{background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important;color:#000!important;-webkit-print-color-adjust:economy;print-color-adjust:economy;text-shadow:none!important}.show-for-print{display:block!important}.hide-for-print{display:none!important}table.show-for-print{display:table!important}thead.show-for-print{display:table-header-group!important}tbody.show-for-print{display:table-row-group!important}tr.show-for-print{display:table-row!important}td.show-for-print,th.show-for-print{display:table-cell!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}abbr[title]:after{content:" (" attr(title) ")"}blockquote,pre{border:1px solid #8a8a8a;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.print-break-inside{page-break-inside:auto}}.grid-container{margin-left:auto;margin-right:auto;max-width:75rem;padding-left:.625rem;padding-right:.625rem}@media print,screen and (min-width:40em){.grid-container{padding-left:.9375rem;padding-right:.9375rem}}.grid-container.fluid{margin-left:auto;margin-right:auto;max-width:100%;padding-left:.625rem;padding-right:.625rem}@media print,screen and (min-width:40em){.grid-container.fluid{padding-left:.9375rem;padding-right:.9375rem}}.grid-container.full{margin-left:auto;margin-right:auto;max-width:100%;padding-left:0;padding-right:0}.grid-x{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap}.cell{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;min-height:0;min-width:0;width:100%}.cell.auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0}.cell.shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-x>.auto,.grid-x>.shrink{width:auto}.grid-x>.small-1,.grid-x>.small-10,.grid-x>.small-11,.grid-x>.small-12,.grid-x>.small-2,.grid-x>.small-3,.grid-x>.small-4,.grid-x>.small-5,.grid-x>.small-6,.grid-x>.small-7,.grid-x>.small-8,.grid-x>.small-9,.grid-x>.small-full,.grid-x>.small-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}@media print,screen and (min-width:40em){.grid-x>.medium-1,.grid-x>.medium-10,.grid-x>.medium-11,.grid-x>.medium-12,.grid-x>.medium-2,.grid-x>.medium-3,.grid-x>.medium-4,.grid-x>.medium-5,.grid-x>.medium-6,.grid-x>.medium-7,.grid-x>.medium-8,.grid-x>.medium-9,.grid-x>.medium-full,.grid-x>.medium-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}}@media print,screen and (min-width:64em){.grid-x>.large-1,.grid-x>.large-10,.grid-x>.large-11,.grid-x>.large-12,.grid-x>.large-2,.grid-x>.large-3,.grid-x>.large-4,.grid-x>.large-5,.grid-x>.large-6,.grid-x>.large-7,.grid-x>.large-8,.grid-x>.large-9,.grid-x>.large-full,.grid-x>.large-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}}.grid-x>.small-1,.grid-x>.small-10,.grid-x>.small-11,.grid-x>.small-12,.grid-x>.small-2,.grid-x>.small-3,.grid-x>.small-4,.grid-x>.small-5,.grid-x>.small-6,.grid-x>.small-7,.grid-x>.small-8,.grid-x>.small-9{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-x>.small-1{width:8.3333333333%}.grid-x>.small-2{width:16.6666666667%}.grid-x>.small-3{width:25%}.grid-x>.small-4{width:33.3333333333%}.grid-x>.small-5{width:41.6666666667%}.grid-x>.small-6{width:50%}.grid-x>.small-7{width:58.3333333333%}.grid-x>.small-8{width:66.6666666667%}.grid-x>.small-9{width:75%}.grid-x>.small-10{width:83.3333333333%}.grid-x>.small-11{width:91.6666666667%}.grid-x>.small-12{width:100%}@media print,screen and (min-width:40em){.grid-x>.medium-auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;width:auto}.grid-x>.medium-1,.grid-x>.medium-10,.grid-x>.medium-11,.grid-x>.medium-12,.grid-x>.medium-2,.grid-x>.medium-3,.grid-x>.medium-4,.grid-x>.medium-5,.grid-x>.medium-6,.grid-x>.medium-7,.grid-x>.medium-8,.grid-x>.medium-9,.grid-x>.medium-shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-x>.medium-shrink{width:auto}.grid-x>.medium-1{width:8.3333333333%}.grid-x>.medium-2{width:16.6666666667%}.grid-x>.medium-3{width:25%}.grid-x>.medium-4{width:33.3333333333%}.grid-x>.medium-5{width:41.6666666667%}.grid-x>.medium-6{width:50%}.grid-x>.medium-7{width:58.3333333333%}.grid-x>.medium-8{width:66.6666666667%}.grid-x>.medium-9{width:75%}.grid-x>.medium-10{width:83.3333333333%}.grid-x>.medium-11{width:91.6666666667%}.grid-x>.medium-12{width:100%}}@media print,screen and (min-width:64em){.grid-x>.large-auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;width:auto}.grid-x>.large-1,.grid-x>.large-10,.grid-x>.large-11,.grid-x>.large-12,.grid-x>.large-2,.grid-x>.large-3,.grid-x>.large-4,.grid-x>.large-5,.grid-x>.large-6,.grid-x>.large-7,.grid-x>.large-8,.grid-x>.large-9,.grid-x>.large-shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-x>.large-shrink{width:auto}.grid-x>.large-1{width:8.3333333333%}.grid-x>.large-2{width:16.6666666667%}.grid-x>.large-3{width:25%}.grid-x>.large-4{width:33.3333333333%}.grid-x>.large-5{width:41.6666666667%}.grid-x>.large-6{width:50%}.grid-x>.large-7{width:58.3333333333%}.grid-x>.large-8{width:66.6666666667%}.grid-x>.large-9{width:75%}.grid-x>.large-10{width:83.3333333333%}.grid-x>.large-11{width:91.6666666667%}.grid-x>.large-12{width:100%}}.grid-margin-x:not(.grid-x)>.cell{width:auto}.grid-margin-y:not(.grid-y)>.cell{height:auto}.grid-margin-x{margin-left:-.625rem;margin-right:-.625rem}@media print,screen and (min-width:40em){.grid-margin-x{margin-left:-.9375rem;margin-right:-.9375rem}}.grid-margin-x>.cell{margin-left:.625rem;margin-right:.625rem;width:calc(100% - 1.25rem)}@media print,screen and (min-width:40em){.grid-margin-x>.cell{margin-left:.9375rem;margin-right:.9375rem;width:calc(100% - 1.875rem)}}.grid-margin-x>.auto,.grid-margin-x>.shrink{width:auto}.grid-margin-x>.small-1{width:calc(8.33333% - 1.25rem)}.grid-margin-x>.small-2{width:calc(16.66667% - 1.25rem)}.grid-margin-x>.small-3{width:calc(25% - 1.25rem)}.grid-margin-x>.small-4{width:calc(33.33333% - 1.25rem)}.grid-margin-x>.small-5{width:calc(41.66667% - 1.25rem)}.grid-margin-x>.small-6{width:calc(50% - 1.25rem)}.grid-margin-x>.small-7{width:calc(58.33333% - 1.25rem)}.grid-margin-x>.small-8{width:calc(66.66667% - 1.25rem)}.grid-margin-x>.small-9{width:calc(75% - 1.25rem)}.grid-margin-x>.small-10{width:calc(83.33333% - 1.25rem)}.grid-margin-x>.small-11{width:calc(91.66667% - 1.25rem)}.grid-margin-x>.small-12{width:calc(100% - 1.25rem)}@media print,screen and (min-width:40em){.grid-margin-x>.auto,.grid-margin-x>.shrink{width:auto}.grid-margin-x>.small-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.small-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.small-3{width:calc(25% - 1.875rem)}.grid-margin-x>.small-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.small-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.small-6{width:calc(50% - 1.875rem)}.grid-margin-x>.small-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.small-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.small-9{width:calc(75% - 1.875rem)}.grid-margin-x>.small-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.small-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.small-12{width:calc(100% - 1.875rem)}.grid-margin-x>.medium-auto,.grid-margin-x>.medium-shrink{width:auto}.grid-margin-x>.medium-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.medium-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.medium-3{width:calc(25% - 1.875rem)}.grid-margin-x>.medium-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.medium-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.medium-6{width:calc(50% - 1.875rem)}.grid-margin-x>.medium-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.medium-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.medium-9{width:calc(75% - 1.875rem)}.grid-margin-x>.medium-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.medium-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.medium-12{width:calc(100% - 1.875rem)}}@media print,screen and (min-width:64em){.grid-margin-x>.large-auto,.grid-margin-x>.large-shrink{width:auto}.grid-margin-x>.large-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.large-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.large-3{width:calc(25% - 1.875rem)}.grid-margin-x>.large-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.large-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.large-6{width:calc(50% - 1.875rem)}.grid-margin-x>.large-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.large-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.large-9{width:calc(75% - 1.875rem)}.grid-margin-x>.large-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.large-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.large-12{width:calc(100% - 1.875rem)}}.grid-padding-x .grid-padding-x{margin-left:-.625rem;margin-right:-.625rem}@media print,screen and (min-width:40em){.grid-padding-x .grid-padding-x{margin-left:-.9375rem;margin-right:-.9375rem}}.grid-container:not(.full)>.grid-padding-x{margin-left:-.625rem;margin-right:-.625rem}@media print,screen and (min-width:40em){.grid-container:not(.full)>.grid-padding-x{margin-left:-.9375rem;margin-right:-.9375rem}}.grid-padding-x>.cell{padding-left:.625rem;padding-right:.625rem}@media print,screen and (min-width:40em){.grid-padding-x>.cell{padding-left:.9375rem;padding-right:.9375rem}}.small-up-1>.cell{width:100%}.small-up-2>.cell{width:50%}.small-up-3>.cell{width:33.3333333333%}.small-up-4>.cell{width:25%}.small-up-5>.cell{width:20%}.small-up-6>.cell{width:16.6666666667%}.small-up-7>.cell{width:14.2857142857%}.small-up-8>.cell{width:12.5%}@media print,screen and (min-width:40em){.medium-up-1>.cell{width:100%}.medium-up-2>.cell{width:50%}.medium-up-3>.cell{width:33.3333333333%}.medium-up-4>.cell{width:25%}.medium-up-5>.cell{width:20%}.medium-up-6>.cell{width:16.6666666667%}.medium-up-7>.cell{width:14.2857142857%}.medium-up-8>.cell{width:12.5%}}@media print,screen and (min-width:64em){.large-up-1>.cell{width:100%}.large-up-2>.cell{width:50%}.large-up-3>.cell{width:33.3333333333%}.large-up-4>.cell{width:25%}.large-up-5>.cell{width:20%}.large-up-6>.cell{width:16.6666666667%}.large-up-7>.cell{width:14.2857142857%}.large-up-8>.cell{width:12.5%}}.grid-margin-x.small-up-1>.cell{width:calc(100% - 1.25rem)}.grid-margin-x.small-up-2>.cell{width:calc(50% - 1.25rem)}.grid-margin-x.small-up-3>.cell{width:calc(33.33333% - 1.25rem)}.grid-margin-x.small-up-4>.cell{width:calc(25% - 1.25rem)}.grid-margin-x.small-up-5>.cell{width:calc(20% - 1.25rem)}.grid-margin-x.small-up-6>.cell{width:calc(16.66667% - 1.25rem)}.grid-margin-x.small-up-7>.cell{width:calc(14.28571% - 1.25rem)}.grid-margin-x.small-up-8>.cell{width:calc(12.5% - 1.25rem)}@media print,screen and (min-width:40em){.grid-margin-x.small-up-1>.cell{width:calc(100% - 1.875rem)}.grid-margin-x.small-up-2>.cell{width:calc(50% - 1.875rem)}.grid-margin-x.small-up-3>.cell{width:calc(33.33333% - 1.875rem)}.grid-margin-x.small-up-4>.cell{width:calc(25% - 1.875rem)}.grid-margin-x.small-up-5>.cell{width:calc(20% - 1.875rem)}.grid-margin-x.small-up-6>.cell{width:calc(16.66667% - 1.875rem)}.grid-margin-x.small-up-7>.cell{width:calc(14.28571% - 1.875rem)}.grid-margin-x.small-up-8>.cell{width:calc(12.5% - 1.875rem)}.grid-margin-x.medium-up-1>.cell{width:calc(100% - 1.875rem)}.grid-margin-x.medium-up-2>.cell{width:calc(50% - 1.875rem)}.grid-margin-x.medium-up-3>.cell{width:calc(33.33333% - 1.875rem)}.grid-margin-x.medium-up-4>.cell{width:calc(25% - 1.875rem)}.grid-margin-x.medium-up-5>.cell{width:calc(20% - 1.875rem)}.grid-margin-x.medium-up-6>.cell{width:calc(16.66667% - 1.875rem)}.grid-margin-x.medium-up-7>.cell{width:calc(14.28571% - 1.875rem)}.grid-margin-x.medium-up-8>.cell{width:calc(12.5% - 1.875rem)}}@media print,screen and (min-width:64em){.grid-margin-x.large-up-1>.cell{width:calc(100% - 1.875rem)}.grid-margin-x.large-up-2>.cell{width:calc(50% - 1.875rem)}.grid-margin-x.large-up-3>.cell{width:calc(33.33333% - 1.875rem)}.grid-margin-x.large-up-4>.cell{width:calc(25% - 1.875rem)}.grid-margin-x.large-up-5>.cell{width:calc(20% - 1.875rem)}.grid-margin-x.large-up-6>.cell{width:calc(16.66667% - 1.875rem)}.grid-margin-x.large-up-7>.cell{width:calc(14.28571% - 1.875rem)}.grid-margin-x.large-up-8>.cell{width:calc(12.5% - 1.875rem)}}.small-margin-collapse,.small-margin-collapse>.cell{margin-left:0;margin-right:0}.small-margin-collapse>.small-1{width:8.3333333333%}.small-margin-collapse>.small-2{width:16.6666666667%}.small-margin-collapse>.small-3{width:25%}.small-margin-collapse>.small-4{width:33.3333333333%}.small-margin-collapse>.small-5{width:41.6666666667%}.small-margin-collapse>.small-6{width:50%}.small-margin-collapse>.small-7{width:58.3333333333%}.small-margin-collapse>.small-8{width:66.6666666667%}.small-margin-collapse>.small-9{width:75%}.small-margin-collapse>.small-10{width:83.3333333333%}.small-margin-collapse>.small-11{width:91.6666666667%}.small-margin-collapse>.small-12{width:100%}@media print,screen and (min-width:40em){.small-margin-collapse>.medium-1{width:8.3333333333%}.small-margin-collapse>.medium-2{width:16.6666666667%}.small-margin-collapse>.medium-3{width:25%}.small-margin-collapse>.medium-4{width:33.3333333333%}.small-margin-collapse>.medium-5{width:41.6666666667%}.small-margin-collapse>.medium-6{width:50%}.small-margin-collapse>.medium-7{width:58.3333333333%}.small-margin-collapse>.medium-8{width:66.6666666667%}.small-margin-collapse>.medium-9{width:75%}.small-margin-collapse>.medium-10{width:83.3333333333%}.small-margin-collapse>.medium-11{width:91.6666666667%}.small-margin-collapse>.medium-12{width:100%}}@media print,screen and (min-width:64em){.small-margin-collapse>.large-1{width:8.3333333333%}.small-margin-collapse>.large-2{width:16.6666666667%}.small-margin-collapse>.large-3{width:25%}.small-margin-collapse>.large-4{width:33.3333333333%}.small-margin-collapse>.large-5{width:41.6666666667%}.small-margin-collapse>.large-6{width:50%}.small-margin-collapse>.large-7{width:58.3333333333%}.small-margin-collapse>.large-8{width:66.6666666667%}.small-margin-collapse>.large-9{width:75%}.small-margin-collapse>.large-10{width:83.3333333333%}.small-margin-collapse>.large-11{width:91.6666666667%}.small-margin-collapse>.large-12{width:100%}}.small-padding-collapse{margin-left:0;margin-right:0}.small-padding-collapse>.cell{padding-left:0;padding-right:0}@media print,screen and (min-width:40em){.medium-margin-collapse,.medium-margin-collapse>.cell{margin-left:0;margin-right:0}.medium-margin-collapse>.small-1{width:8.3333333333%}.medium-margin-collapse>.small-2{width:16.6666666667%}.medium-margin-collapse>.small-3{width:25%}.medium-margin-collapse>.small-4{width:33.3333333333%}.medium-margin-collapse>.small-5{width:41.6666666667%}.medium-margin-collapse>.small-6{width:50%}.medium-margin-collapse>.small-7{width:58.3333333333%}.medium-margin-collapse>.small-8{width:66.6666666667%}.medium-margin-collapse>.small-9{width:75%}.medium-margin-collapse>.small-10{width:83.3333333333%}.medium-margin-collapse>.small-11{width:91.6666666667%}.medium-margin-collapse>.small-12{width:100%}.medium-margin-collapse>.medium-1{width:8.3333333333%}.medium-margin-collapse>.medium-2{width:16.6666666667%}.medium-margin-collapse>.medium-3{width:25%}.medium-margin-collapse>.medium-4{width:33.3333333333%}.medium-margin-collapse>.medium-5{width:41.6666666667%}.medium-margin-collapse>.medium-6{width:50%}.medium-margin-collapse>.medium-7{width:58.3333333333%}.medium-margin-collapse>.medium-8{width:66.6666666667%}.medium-margin-collapse>.medium-9{width:75%}.medium-margin-collapse>.medium-10{width:83.3333333333%}.medium-margin-collapse>.medium-11{width:91.6666666667%}.medium-margin-collapse>.medium-12{width:100%}}@media print,screen and (min-width:64em){.medium-margin-collapse>.large-1{width:8.3333333333%}.medium-margin-collapse>.large-2{width:16.6666666667%}.medium-margin-collapse>.large-3{width:25%}.medium-margin-collapse>.large-4{width:33.3333333333%}.medium-margin-collapse>.large-5{width:41.6666666667%}.medium-margin-collapse>.large-6{width:50%}.medium-margin-collapse>.large-7{width:58.3333333333%}.medium-margin-collapse>.large-8{width:66.6666666667%}.medium-margin-collapse>.large-9{width:75%}.medium-margin-collapse>.large-10{width:83.3333333333%}.medium-margin-collapse>.large-11{width:91.6666666667%}.medium-margin-collapse>.large-12{width:100%}}@media print,screen and (min-width:40em){.medium-padding-collapse{margin-left:0;margin-right:0}.medium-padding-collapse>.cell{padding-left:0;padding-right:0}}@media print,screen and (min-width:64em){.large-margin-collapse,.large-margin-collapse>.cell{margin-left:0;margin-right:0}.large-margin-collapse>.small-1{width:8.3333333333%}.large-margin-collapse>.small-2{width:16.6666666667%}.large-margin-collapse>.small-3{width:25%}.large-margin-collapse>.small-4{width:33.3333333333%}.large-margin-collapse>.small-5{width:41.6666666667%}.large-margin-collapse>.small-6{width:50%}.large-margin-collapse>.small-7{width:58.3333333333%}.large-margin-collapse>.small-8{width:66.6666666667%}.large-margin-collapse>.small-9{width:75%}.large-margin-collapse>.small-10{width:83.3333333333%}.large-margin-collapse>.small-11{width:91.6666666667%}.large-margin-collapse>.small-12{width:100%}.large-margin-collapse>.medium-1{width:8.3333333333%}.large-margin-collapse>.medium-2{width:16.6666666667%}.large-margin-collapse>.medium-3{width:25%}.large-margin-collapse>.medium-4{width:33.3333333333%}.large-margin-collapse>.medium-5{width:41.6666666667%}.large-margin-collapse>.medium-6{width:50%}.large-margin-collapse>.medium-7{width:58.3333333333%}.large-margin-collapse>.medium-8{width:66.6666666667%}.large-margin-collapse>.medium-9{width:75%}.large-margin-collapse>.medium-10{width:83.3333333333%}.large-margin-collapse>.medium-11{width:91.6666666667%}.large-margin-collapse>.medium-12{width:100%}.large-margin-collapse>.large-1{width:8.3333333333%}.large-margin-collapse>.large-2{width:16.6666666667%}.large-margin-collapse>.large-3{width:25%}.large-margin-collapse>.large-4{width:33.3333333333%}.large-margin-collapse>.large-5{width:41.6666666667%}.large-margin-collapse>.large-6{width:50%}.large-margin-collapse>.large-7{width:58.3333333333%}.large-margin-collapse>.large-8{width:66.6666666667%}.large-margin-collapse>.large-9{width:75%}.large-margin-collapse>.large-10{width:83.3333333333%}.large-margin-collapse>.large-11{width:91.6666666667%}.large-margin-collapse>.large-12{width:100%}.large-padding-collapse{margin-left:0;margin-right:0}.large-padding-collapse>.cell{padding-left:0;padding-right:0}}.small-offset-0{margin-left:0}.grid-margin-x>.small-offset-0{margin-left:.625rem}.small-offset-1{margin-left:8.3333333333%}.grid-margin-x>.small-offset-1{margin-left:calc(8.33333% + .625rem)}.small-offset-2{margin-left:16.6666666667%}.grid-margin-x>.small-offset-2{margin-left:calc(16.66667% + .625rem)}.small-offset-3{margin-left:25%}.grid-margin-x>.small-offset-3{margin-left:calc(25% + .625rem)}.small-offset-4{margin-left:33.3333333333%}.grid-margin-x>.small-offset-4{margin-left:calc(33.33333% + .625rem)}.small-offset-5{margin-left:41.6666666667%}.grid-margin-x>.small-offset-5{margin-left:calc(41.66667% + .625rem)}.small-offset-6{margin-left:50%}.grid-margin-x>.small-offset-6{margin-left:calc(50% + .625rem)}.small-offset-7{margin-left:58.3333333333%}.grid-margin-x>.small-offset-7{margin-left:calc(58.33333% + .625rem)}.small-offset-8{margin-left:66.6666666667%}.grid-margin-x>.small-offset-8{margin-left:calc(66.66667% + .625rem)}.small-offset-9{margin-left:75%}.grid-margin-x>.small-offset-9{margin-left:calc(75% + .625rem)}.small-offset-10{margin-left:83.3333333333%}.grid-margin-x>.small-offset-10{margin-left:calc(83.33333% + .625rem)}.small-offset-11{margin-left:91.6666666667%}.grid-margin-x>.small-offset-11{margin-left:calc(91.66667% + .625rem)}@media print,screen and (min-width:40em){.medium-offset-0{margin-left:0}.grid-margin-x>.medium-offset-0{margin-left:.9375rem}.medium-offset-1{margin-left:8.3333333333%}.grid-margin-x>.medium-offset-1{margin-left:calc(8.33333% + .9375rem)}.medium-offset-2{margin-left:16.6666666667%}.grid-margin-x>.medium-offset-2{margin-left:calc(16.66667% + .9375rem)}.medium-offset-3{margin-left:25%}.grid-margin-x>.medium-offset-3{margin-left:calc(25% + .9375rem)}.medium-offset-4{margin-left:33.3333333333%}.grid-margin-x>.medium-offset-4{margin-left:calc(33.33333% + .9375rem)}.medium-offset-5{margin-left:41.6666666667%}.grid-margin-x>.medium-offset-5{margin-left:calc(41.66667% + .9375rem)}.medium-offset-6{margin-left:50%}.grid-margin-x>.medium-offset-6{margin-left:calc(50% + .9375rem)}.medium-offset-7{margin-left:58.3333333333%}.grid-margin-x>.medium-offset-7{margin-left:calc(58.33333% + .9375rem)}.medium-offset-8{margin-left:66.6666666667%}.grid-margin-x>.medium-offset-8{margin-left:calc(66.66667% + .9375rem)}.medium-offset-9{margin-left:75%}.grid-margin-x>.medium-offset-9{margin-left:calc(75% + .9375rem)}.medium-offset-10{margin-left:83.3333333333%}.grid-margin-x>.medium-offset-10{margin-left:calc(83.33333% + .9375rem)}.medium-offset-11{margin-left:91.6666666667%}.grid-margin-x>.medium-offset-11{margin-left:calc(91.66667% + .9375rem)}}@media print,screen and (min-width:64em){.large-offset-0{margin-left:0}.grid-margin-x>.large-offset-0{margin-left:.9375rem}.large-offset-1{margin-left:8.3333333333%}.grid-margin-x>.large-offset-1{margin-left:calc(8.33333% + .9375rem)}.large-offset-2{margin-left:16.6666666667%}.grid-margin-x>.large-offset-2{margin-left:calc(16.66667% + .9375rem)}.large-offset-3{margin-left:25%}.grid-margin-x>.large-offset-3{margin-left:calc(25% + .9375rem)}.large-offset-4{margin-left:33.3333333333%}.grid-margin-x>.large-offset-4{margin-left:calc(33.33333% + .9375rem)}.large-offset-5{margin-left:41.6666666667%}.grid-margin-x>.large-offset-5{margin-left:calc(41.66667% + .9375rem)}.large-offset-6{margin-left:50%}.grid-margin-x>.large-offset-6{margin-left:calc(50% + .9375rem)}.large-offset-7{margin-left:58.3333333333%}.grid-margin-x>.large-offset-7{margin-left:calc(58.33333% + .9375rem)}.large-offset-8{margin-left:66.6666666667%}.grid-margin-x>.large-offset-8{margin-left:calc(66.66667% + .9375rem)}.large-offset-9{margin-left:75%}.grid-margin-x>.large-offset-9{margin-left:calc(75% + .9375rem)}.large-offset-10{margin-left:83.3333333333%}.grid-margin-x>.large-offset-10{margin-left:calc(83.33333% + .9375rem)}.large-offset-11{margin-left:91.6666666667%}.grid-margin-x>.large-offset-11{margin-left:calc(91.66667% + .9375rem)}}.grid-y{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:column nowrap;-ms-flex-flow:column nowrap;flex-flow:column nowrap}.grid-y>.cell{height:auto;max-height:none}.grid-y>.auto,.grid-y>.shrink{height:auto}.grid-y>.small-1,.grid-y>.small-10,.grid-y>.small-11,.grid-y>.small-12,.grid-y>.small-2,.grid-y>.small-3,.grid-y>.small-4,.grid-y>.small-5,.grid-y>.small-6,.grid-y>.small-7,.grid-y>.small-8,.grid-y>.small-9,.grid-y>.small-full,.grid-y>.small-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}@media print,screen and (min-width:40em){.grid-y>.medium-1,.grid-y>.medium-10,.grid-y>.medium-11,.grid-y>.medium-12,.grid-y>.medium-2,.grid-y>.medium-3,.grid-y>.medium-4,.grid-y>.medium-5,.grid-y>.medium-6,.grid-y>.medium-7,.grid-y>.medium-8,.grid-y>.medium-9,.grid-y>.medium-full,.grid-y>.medium-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}}@media print,screen and (min-width:64em){.grid-y>.large-1,.grid-y>.large-10,.grid-y>.large-11,.grid-y>.large-12,.grid-y>.large-2,.grid-y>.large-3,.grid-y>.large-4,.grid-y>.large-5,.grid-y>.large-6,.grid-y>.large-7,.grid-y>.large-8,.grid-y>.large-9,.grid-y>.large-full,.grid-y>.large-shrink{-ms-flex-preferred-size:auto;-webkit-flex-basis:auto;flex-basis:auto}}.grid-y>.small-1,.grid-y>.small-10,.grid-y>.small-11,.grid-y>.small-12,.grid-y>.small-2,.grid-y>.small-3,.grid-y>.small-4,.grid-y>.small-5,.grid-y>.small-6,.grid-y>.small-7,.grid-y>.small-8,.grid-y>.small-9{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-y>.small-1{height:8.3333333333%}.grid-y>.small-2{height:16.6666666667%}.grid-y>.small-3{height:25%}.grid-y>.small-4{height:33.3333333333%}.grid-y>.small-5{height:41.6666666667%}.grid-y>.small-6{height:50%}.grid-y>.small-7{height:58.3333333333%}.grid-y>.small-8{height:66.6666666667%}.grid-y>.small-9{height:75%}.grid-y>.small-10{height:83.3333333333%}.grid-y>.small-11{height:91.6666666667%}.grid-y>.small-12{height:100%}@media print,screen and (min-width:40em){.grid-y>.medium-auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;height:auto}.grid-y>.medium-1,.grid-y>.medium-10,.grid-y>.medium-11,.grid-y>.medium-12,.grid-y>.medium-2,.grid-y>.medium-3,.grid-y>.medium-4,.grid-y>.medium-5,.grid-y>.medium-6,.grid-y>.medium-7,.grid-y>.medium-8,.grid-y>.medium-9,.grid-y>.medium-shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-y>.medium-shrink{height:auto}.grid-y>.medium-1{height:8.3333333333%}.grid-y>.medium-2{height:16.6666666667%}.grid-y>.medium-3{height:25%}.grid-y>.medium-4{height:33.3333333333%}.grid-y>.medium-5{height:41.6666666667%}.grid-y>.medium-6{height:50%}.grid-y>.medium-7{height:58.3333333333%}.grid-y>.medium-8{height:66.6666666667%}.grid-y>.medium-9{height:75%}.grid-y>.medium-10{height:83.3333333333%}.grid-y>.medium-11{height:91.6666666667%}.grid-y>.medium-12{height:100%}}@media print,screen and (min-width:64em){.grid-y>.large-auto{-webkit-box-flex:1;-webkit-flex:1 1 0;-ms-flex:1 1 0px;flex:1 1 0;height:auto}.grid-y>.large-1,.grid-y>.large-10,.grid-y>.large-11,.grid-y>.large-12,.grid-y>.large-2,.grid-y>.large-3,.grid-y>.large-4,.grid-y>.large-5,.grid-y>.large-6,.grid-y>.large-7,.grid-y>.large-8,.grid-y>.large-9,.grid-y>.large-shrink{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.grid-y>.large-shrink{height:auto}.grid-y>.large-1{height:8.3333333333%}.grid-y>.large-2{height:16.6666666667%}.grid-y>.large-3{height:25%}.grid-y>.large-4{height:33.3333333333%}.grid-y>.large-5{height:41.6666666667%}.grid-y>.large-6{height:50%}.grid-y>.large-7{height:58.3333333333%}.grid-y>.large-8{height:66.6666666667%}.grid-y>.large-9{height:75%}.grid-y>.large-10{height:83.3333333333%}.grid-y>.large-11{height:91.6666666667%}.grid-y>.large-12{height:100%}}.grid-padding-y .grid-padding-y{margin-bottom:-.625rem;margin-top:-.625rem}@media print,screen and (min-width:40em){.grid-padding-y .grid-padding-y{margin-bottom:-.9375rem;margin-top:-.9375rem}}.grid-padding-y>.cell{padding-bottom:.625rem;padding-top:.625rem}@media print,screen and (min-width:40em){.grid-padding-y>.cell{padding-bottom:.9375rem;padding-top:.9375rem}}.grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;overflow:hidden;position:relative;width:100vw}.cell .grid-frame{width:100%}.cell-block{max-width:100%;overflow-x:auto}.cell-block,.cell-block-y{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.cell-block-y{max-height:100%;min-height:100%;overflow-y:auto}.cell-block-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-height:100%}.cell-block-container>.grid-x{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;max-height:100%}@media print,screen and (min-width:40em){.medium-grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;overflow:hidden;position:relative;width:100vw}.cell .medium-grid-frame{width:100%}.medium-cell-block{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;max-width:100%;overflow-x:auto}.medium-cell-block-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-height:100%}.medium-cell-block-container>.grid-x{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;max-height:100%}.medium-cell-block-y{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;max-height:100%;min-height:100%;overflow-y:auto}}@media print,screen and (min-width:64em){.large-grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;overflow:hidden;position:relative;width:100vw}.cell .large-grid-frame{width:100%}.large-cell-block{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;max-width:100%;overflow-x:auto}.large-cell-block-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-height:100%}.large-cell-block-container>.grid-x{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;max-height:100%}.large-cell-block-y{-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;max-height:100%;min-height:100%;overflow-y:auto}}.grid-y.grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;height:100vh;overflow:hidden;position:relative;width:auto}@media print,screen and (min-width:40em){.grid-y.medium-grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;height:100vh;overflow:hidden;position:relative;width:auto}}@media print,screen and (min-width:64em){.grid-y.large-grid-frame{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;height:100vh;overflow:hidden;position:relative;width:auto}}.cell .grid-y.grid-frame{height:100%}@media print,screen and (min-width:40em){.cell .grid-y.medium-grid-frame{height:100%}}@media print,screen and (min-width:64em){.cell .grid-y.large-grid-frame{height:100%}}.grid-margin-y{margin-bottom:-.625rem;margin-top:-.625rem}@media print,screen and (min-width:40em){.grid-margin-y{margin-bottom:-.9375rem;margin-top:-.9375rem}}.grid-margin-y>.cell{height:calc(100% - 1.25rem);margin-bottom:.625rem;margin-top:.625rem}@media print,screen and (min-width:40em){.grid-margin-y>.cell{height:calc(100% - 1.875rem);margin-bottom:.9375rem;margin-top:.9375rem}}.grid-margin-y>.auto,.grid-margin-y>.shrink{height:auto}.grid-margin-y>.small-1{height:calc(8.33333% - 1.25rem)}.grid-margin-y>.small-2{height:calc(16.66667% - 1.25rem)}.grid-margin-y>.small-3{height:calc(25% - 1.25rem)}.grid-margin-y>.small-4{height:calc(33.33333% - 1.25rem)}.grid-margin-y>.small-5{height:calc(41.66667% - 1.25rem)}.grid-margin-y>.small-6{height:calc(50% - 1.25rem)}.grid-margin-y>.small-7{height:calc(58.33333% - 1.25rem)}.grid-margin-y>.small-8{height:calc(66.66667% - 1.25rem)}.grid-margin-y>.small-9{height:calc(75% - 1.25rem)}.grid-margin-y>.small-10{height:calc(83.33333% - 1.25rem)}.grid-margin-y>.small-11{height:calc(91.66667% - 1.25rem)}.grid-margin-y>.small-12{height:calc(100% - 1.25rem)}@media print,screen and (min-width:40em){.grid-margin-y>.auto,.grid-margin-y>.shrink{height:auto}.grid-margin-y>.small-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.small-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.small-3{height:calc(25% - 1.875rem)}.grid-margin-y>.small-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.small-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.small-6{height:calc(50% - 1.875rem)}.grid-margin-y>.small-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.small-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.small-9{height:calc(75% - 1.875rem)}.grid-margin-y>.small-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.small-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.small-12{height:calc(100% - 1.875rem)}.grid-margin-y>.medium-auto,.grid-margin-y>.medium-shrink{height:auto}.grid-margin-y>.medium-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.medium-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.medium-3{height:calc(25% - 1.875rem)}.grid-margin-y>.medium-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.medium-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.medium-6{height:calc(50% - 1.875rem)}.grid-margin-y>.medium-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.medium-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.medium-9{height:calc(75% - 1.875rem)}.grid-margin-y>.medium-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.medium-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.medium-12{height:calc(100% - 1.875rem)}}@media print,screen and (min-width:64em){.grid-margin-y>.large-auto,.grid-margin-y>.large-shrink{height:auto}.grid-margin-y>.large-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.large-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.large-3{height:calc(25% - 1.875rem)}.grid-margin-y>.large-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.large-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.large-6{height:calc(50% - 1.875rem)}.grid-margin-y>.large-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.large-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.large-9{height:calc(75% - 1.875rem)}.grid-margin-y>.large-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.large-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.large-12{height:calc(100% - 1.875rem)}}.grid-frame.grid-margin-y{height:calc(100vh + 1.25rem)}@media print,screen and (min-width:40em){.grid-frame.grid-margin-y{height:calc(100vh + 1.875rem)}}@media print,screen and (min-width:64em){.grid-frame.grid-margin-y{height:calc(100vh + 1.875rem)}}@media print,screen and (min-width:40em){.grid-margin-y.medium-grid-frame{height:calc(100vh + 1.875rem)}}@media print,screen and (min-width:64em){.grid-margin-y.large-grid-frame{height:calc(100vh + 1.875rem)}}.button{-webkit-appearance:none;border:1px solid transparent;border-radius:0;cursor:pointer;display:inline-block;font-family:inherit;font-size:.9rem;line-height:1;margin:0 0 1rem;padding:.85em 1em;text-align:center;-webkit-transition:background-color .25s ease-out,color .25s ease-out;transition:background-color .25s ease-out,color .25s ease-out;vertical-align:middle}[data-whatinput=mouse] .button{outline:0}.button.tiny{font-size:.6rem}.button.small{font-size:.75rem}.button.large{font-size:1.25rem}.button.expanded{display:block;margin-left:0;margin-right:0;width:100%}.button,.button.disabled,.button.disabled:focus,.button.disabled:hover,.button[disabled],.button[disabled]:focus,.button[disabled]:hover{background-color:#1779ba;color:#fefefe}.button:focus,.button:hover{background-color:#14679e;color:#fefefe}.button.primary,.button.primary.disabled,.button.primary.disabled:focus,.button.primary.disabled:hover,.button.primary[disabled],.button.primary[disabled]:focus,.button.primary[disabled]:hover{background-color:#1779ba;color:#fefefe}.button.primary:focus,.button.primary:hover{background-color:#126195;color:#fefefe}.button.secondary,.button.secondary.disabled,.button.secondary.disabled:focus,.button.secondary.disabled:hover,.button.secondary[disabled],.button.secondary[disabled]:focus,.button.secondary[disabled]:hover{background-color:#767676;color:#fefefe}.button.secondary:focus,.button.secondary:hover{background-color:#5e5e5e;color:#fefefe}.button.success,.button.success.disabled,.button.success.disabled:focus,.button.success.disabled:hover,.button.success[disabled],.button.success[disabled]:focus,.button.success[disabled]:hover{background-color:#3adb76;color:#0a0a0a}.button.success:focus,.button.success:hover{background-color:#22bb5b;color:#0a0a0a}.button.warning,.button.warning.disabled,.button.warning.disabled:focus,.button.warning.disabled:hover,.button.warning[disabled],.button.warning[disabled]:focus,.button.warning[disabled]:hover{background-color:#ffae00;color:#0a0a0a}.button.warning:focus,.button.warning:hover{background-color:#cc8b00;color:#0a0a0a}.button.alert,.button.alert.disabled,.button.alert.disabled:focus,.button.alert.disabled:hover,.button.alert[disabled],.button.alert[disabled]:focus,.button.alert[disabled]:hover{background-color:#cc4b37;color:#fefefe}.button.alert:focus,.button.alert:hover{background-color:#a53b2a;color:#fefefe}.button.hollow,.button.hollow.disabled,.button.hollow.disabled:focus,.button.hollow.disabled:hover,.button.hollow:focus,.button.hollow:hover,.button.hollow[disabled],.button.hollow[disabled]:focus,.button.hollow[disabled]:hover{background-color:transparent}.button.hollow,.button.hollow.disabled,.button.hollow.disabled:focus,.button.hollow.disabled:hover,.button.hollow[disabled],.button.hollow[disabled]:focus,.button.hollow[disabled]:hover{border:1px solid #1779ba;color:#1779ba}.button.hollow:focus,.button.hollow:hover{border-color:#0c3d5d;color:#0c3d5d}.button.hollow.primary,.button.hollow.primary.disabled,.button.hollow.primary.disabled:focus,.button.hollow.primary.disabled:hover,.button.hollow.primary[disabled],.button.hollow.primary[disabled]:focus,.button.hollow.primary[disabled]:hover{border:1px solid #1779ba;color:#1779ba}.button.hollow.primary:focus,.button.hollow.primary:hover{border-color:#0c3d5d;color:#0c3d5d}.button.hollow.secondary,.button.hollow.secondary.disabled,.button.hollow.secondary.disabled:focus,.button.hollow.secondary.disabled:hover,.button.hollow.secondary[disabled],.button.hollow.secondary[disabled]:focus,.button.hollow.secondary[disabled]:hover{border:1px solid #767676;color:#767676}.button.hollow.secondary:focus,.button.hollow.secondary:hover{border-color:#3b3b3b;color:#3b3b3b}.button.hollow.success,.button.hollow.success.disabled,.button.hollow.success.disabled:focus,.button.hollow.success.disabled:hover,.button.hollow.success[disabled],.button.hollow.success[disabled]:focus,.button.hollow.success[disabled]:hover{border:1px solid #3adb76;color:#3adb76}.button.hollow.success:focus,.button.hollow.success:hover{border-color:#157539;color:#157539}.button.hollow.warning,.button.hollow.warning.disabled,.button.hollow.warning.disabled:focus,.button.hollow.warning.disabled:hover,.button.hollow.warning[disabled],.button.hollow.warning[disabled]:focus,.button.hollow.warning[disabled]:hover{border:1px solid #ffae00;color:#ffae00}.button.hollow.warning:focus,.button.hollow.warning:hover{border-color:#805700;color:#805700}.button.hollow.alert,.button.hollow.alert.disabled,.button.hollow.alert.disabled:focus,.button.hollow.alert.disabled:hover,.button.hollow.alert[disabled],.button.hollow.alert[disabled]:focus,.button.hollow.alert[disabled]:hover{border:1px solid #cc4b37;color:#cc4b37}.button.hollow.alert:focus,.button.hollow.alert:hover{border-color:#67251a;color:#67251a}.button.clear,.button.clear.disabled,.button.clear.disabled:focus,.button.clear.disabled:hover,.button.clear:focus,.button.clear:hover,.button.clear[disabled],.button.clear[disabled]:focus,.button.clear[disabled]:hover{background-color:transparent;border-color:transparent}.button.clear,.button.clear.disabled,.button.clear.disabled:focus,.button.clear.disabled:hover,.button.clear[disabled],.button.clear[disabled]:focus,.button.clear[disabled]:hover{color:#1779ba}.button.clear:focus,.button.clear:hover{color:#0c3d5d}.button.clear.primary,.button.clear.primary.disabled,.button.clear.primary.disabled:focus,.button.clear.primary.disabled:hover,.button.clear.primary[disabled],.button.clear.primary[disabled]:focus,.button.clear.primary[disabled]:hover{color:#1779ba}.button.clear.primary:focus,.button.clear.primary:hover{color:#0c3d5d}.button.clear.secondary,.button.clear.secondary.disabled,.button.clear.secondary.disabled:focus,.button.clear.secondary.disabled:hover,.button.clear.secondary[disabled],.button.clear.secondary[disabled]:focus,.button.clear.secondary[disabled]:hover{color:#767676}.button.clear.secondary:focus,.button.clear.secondary:hover{color:#3b3b3b}.button.clear.success,.button.clear.success.disabled,.button.clear.success.disabled:focus,.button.clear.success.disabled:hover,.button.clear.success[disabled],.button.clear.success[disabled]:focus,.button.clear.success[disabled]:hover{color:#3adb76}.button.clear.success:focus,.button.clear.success:hover{color:#157539}.button.clear.warning,.button.clear.warning.disabled,.button.clear.warning.disabled:focus,.button.clear.warning.disabled:hover,.button.clear.warning[disabled],.button.clear.warning[disabled]:focus,.button.clear.warning[disabled]:hover{color:#ffae00}.button.clear.warning:focus,.button.clear.warning:hover{color:#805700}.button.clear.alert,.button.clear.alert.disabled,.button.clear.alert.disabled:focus,.button.clear.alert.disabled:hover,.button.clear.alert[disabled],.button.clear.alert[disabled]:focus,.button.clear.alert[disabled]:hover{color:#cc4b37}.button.clear.alert:focus,.button.clear.alert:hover{color:#67251a}.button.disabled,.button[disabled]{cursor:not-allowed;opacity:.25}.button.dropdown:after{border-color:#fefefe transparent transparent;border-style:solid;border-width:.4em .4em 0;content:"";display:block;display:inline-block;float:right;height:0;margin-left:1em;position:relative;top:.4em;width:0}.button.dropdown.clear.primary:after,.button.dropdown.clear:after,.button.dropdown.hollow.primary:after,.button.dropdown.hollow:after{border-top-color:#1779ba}.button.dropdown.clear.secondary:after,.button.dropdown.hollow.secondary:after{border-top-color:#767676}.button.dropdown.clear.success:after,.button.dropdown.hollow.success:after{border-top-color:#3adb76}.button.dropdown.clear.warning:after,.button.dropdown.hollow.warning:after{border-top-color:#ffae00}.button.dropdown.clear.alert:after,.button.dropdown.hollow.alert:after{border-top-color:#cc4b37}.button.arrow-only:after{float:none;margin-left:0;top:-.1em}a.button:focus,a.button:hover{text-decoration:none}.button-group{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-box-flex:1;-ms-flex-positive:1;-webkit-align-items:stretch;align-items:stretch;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-bottom:1rem}.button-group:after,.button-group:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.button-group:after{clear:both}.button-group:after,.button-group:before{display:none}.button-group .button{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;font-size:.9rem;margin:0 1px 1px 0}.button-group .button:last-child{margin-right:0}.button-group.tiny .button{font-size:.6rem}.button-group.small .button{font-size:.75rem}.button-group.large .button{font-size:1.25rem}.button-group.expanded .button{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}.button-group.primary .button,.button-group.primary .button.disabled,.button-group.primary .button.disabled:focus,.button-group.primary .button.disabled:hover,.button-group.primary .button[disabled],.button-group.primary .button[disabled]:focus,.button-group.primary .button[disabled]:hover{background-color:#1779ba;color:#fefefe}.button-group.primary .button:focus,.button-group.primary .button:hover{background-color:#126195;color:#fefefe}.button-group.secondary .button,.button-group.secondary .button.disabled,.button-group.secondary .button.disabled:focus,.button-group.secondary .button.disabled:hover,.button-group.secondary .button[disabled],.button-group.secondary .button[disabled]:focus,.button-group.secondary .button[disabled]:hover{background-color:#767676;color:#fefefe}.button-group.secondary .button:focus,.button-group.secondary .button:hover{background-color:#5e5e5e;color:#fefefe}.button-group.success .button,.button-group.success .button.disabled,.button-group.success .button.disabled:focus,.button-group.success .button.disabled:hover,.button-group.success .button[disabled],.button-group.success .button[disabled]:focus,.button-group.success .button[disabled]:hover{background-color:#3adb76;color:#0a0a0a}.button-group.success .button:focus,.button-group.success .button:hover{background-color:#22bb5b;color:#0a0a0a}.button-group.warning .button,.button-group.warning .button.disabled,.button-group.warning .button.disabled:focus,.button-group.warning .button.disabled:hover,.button-group.warning .button[disabled],.button-group.warning .button[disabled]:focus,.button-group.warning .button[disabled]:hover{background-color:#ffae00;color:#0a0a0a}.button-group.warning .button:focus,.button-group.warning .button:hover{background-color:#cc8b00;color:#0a0a0a}.button-group.alert .button,.button-group.alert .button.disabled,.button-group.alert .button.disabled:focus,.button-group.alert .button.disabled:hover,.button-group.alert .button[disabled],.button-group.alert .button[disabled]:focus,.button-group.alert .button[disabled]:hover{background-color:#cc4b37;color:#fefefe}.button-group.alert .button:focus,.button-group.alert .button:hover{background-color:#a53b2a;color:#fefefe}.button-group.hollow .button,.button-group.hollow .button.disabled,.button-group.hollow .button.disabled:focus,.button-group.hollow .button.disabled:hover,.button-group.hollow .button:focus,.button-group.hollow .button:hover,.button-group.hollow .button[disabled],.button-group.hollow .button[disabled]:focus,.button-group.hollow .button[disabled]:hover{background-color:transparent}.button-group.hollow .button,.button-group.hollow .button.disabled,.button-group.hollow .button.disabled:focus,.button-group.hollow .button.disabled:hover,.button-group.hollow .button[disabled],.button-group.hollow .button[disabled]:focus,.button-group.hollow .button[disabled]:hover{border:1px solid #1779ba;color:#1779ba}.button-group.hollow .button:focus,.button-group.hollow .button:hover{border-color:#0c3d5d;color:#0c3d5d}.button-group.hollow .button.primary,.button-group.hollow .button.primary.disabled,.button-group.hollow .button.primary.disabled:focus,.button-group.hollow .button.primary.disabled:hover,.button-group.hollow .button.primary[disabled],.button-group.hollow .button.primary[disabled]:focus,.button-group.hollow .button.primary[disabled]:hover,.button-group.hollow.primary .button,.button-group.hollow.primary .button.disabled,.button-group.hollow.primary .button.disabled:focus,.button-group.hollow.primary .button.disabled:hover,.button-group.hollow.primary .button[disabled],.button-group.hollow.primary .button[disabled]:focus,.button-group.hollow.primary .button[disabled]:hover{border:1px solid #1779ba;color:#1779ba}.button-group.hollow .button.primary:focus,.button-group.hollow .button.primary:hover,.button-group.hollow.primary .button:focus,.button-group.hollow.primary .button:hover{border-color:#0c3d5d;color:#0c3d5d}.button-group.hollow .button.secondary,.button-group.hollow .button.secondary.disabled,.button-group.hollow .button.secondary.disabled:focus,.button-group.hollow .button.secondary.disabled:hover,.button-group.hollow .button.secondary[disabled],.button-group.hollow .button.secondary[disabled]:focus,.button-group.hollow .button.secondary[disabled]:hover,.button-group.hollow.secondary .button,.button-group.hollow.secondary .button.disabled,.button-group.hollow.secondary .button.disabled:focus,.button-group.hollow.secondary .button.disabled:hover,.button-group.hollow.secondary .button[disabled],.button-group.hollow.secondary .button[disabled]:focus,.button-group.hollow.secondary .button[disabled]:hover{border:1px solid #767676;color:#767676}.button-group.hollow .button.secondary:focus,.button-group.hollow .button.secondary:hover,.button-group.hollow.secondary .button:focus,.button-group.hollow.secondary .button:hover{border-color:#3b3b3b;color:#3b3b3b}.button-group.hollow .button.success,.button-group.hollow .button.success.disabled,.button-group.hollow .button.success.disabled:focus,.button-group.hollow .button.success.disabled:hover,.button-group.hollow .button.success[disabled],.button-group.hollow .button.success[disabled]:focus,.button-group.hollow .button.success[disabled]:hover,.button-group.hollow.success .button,.button-group.hollow.success .button.disabled,.button-group.hollow.success .button.disabled:focus,.button-group.hollow.success .button.disabled:hover,.button-group.hollow.success .button[disabled],.button-group.hollow.success .button[disabled]:focus,.button-group.hollow.success .button[disabled]:hover{border:1px solid #3adb76;color:#3adb76}.button-group.hollow .button.success:focus,.button-group.hollow .button.success:hover,.button-group.hollow.success .button:focus,.button-group.hollow.success .button:hover{border-color:#157539;color:#157539}.button-group.hollow .button.warning,.button-group.hollow .button.warning.disabled,.button-group.hollow .button.warning.disabled:focus,.button-group.hollow .button.warning.disabled:hover,.button-group.hollow .button.warning[disabled],.button-group.hollow .button.warning[disabled]:focus,.button-group.hollow .button.warning[disabled]:hover,.button-group.hollow.warning .button,.button-group.hollow.warning .button.disabled,.button-group.hollow.warning .button.disabled:focus,.button-group.hollow.warning .button.disabled:hover,.button-group.hollow.warning .button[disabled],.button-group.hollow.warning .button[disabled]:focus,.button-group.hollow.warning .button[disabled]:hover{border:1px solid #ffae00;color:#ffae00}.button-group.hollow .button.warning:focus,.button-group.hollow .button.warning:hover,.button-group.hollow.warning .button:focus,.button-group.hollow.warning .button:hover{border-color:#805700;color:#805700}.button-group.hollow .button.alert,.button-group.hollow .button.alert.disabled,.button-group.hollow .button.alert.disabled:focus,.button-group.hollow .button.alert.disabled:hover,.button-group.hollow .button.alert[disabled],.button-group.hollow .button.alert[disabled]:focus,.button-group.hollow .button.alert[disabled]:hover,.button-group.hollow.alert .button,.button-group.hollow.alert .button.disabled,.button-group.hollow.alert .button.disabled:focus,.button-group.hollow.alert .button.disabled:hover,.button-group.hollow.alert .button[disabled],.button-group.hollow.alert .button[disabled]:focus,.button-group.hollow.alert .button[disabled]:hover{border:1px solid #cc4b37;color:#cc4b37}.button-group.hollow .button.alert:focus,.button-group.hollow .button.alert:hover,.button-group.hollow.alert .button:focus,.button-group.hollow.alert .button:hover{border-color:#67251a;color:#67251a}.button-group.clear .button,.button-group.clear .button.disabled,.button-group.clear .button.disabled:focus,.button-group.clear .button.disabled:hover,.button-group.clear .button:focus,.button-group.clear .button:hover,.button-group.clear .button[disabled],.button-group.clear .button[disabled]:focus,.button-group.clear .button[disabled]:hover{background-color:transparent;border-color:transparent}.button-group.clear .button,.button-group.clear .button.disabled,.button-group.clear .button.disabled:focus,.button-group.clear .button.disabled:hover,.button-group.clear .button[disabled],.button-group.clear .button[disabled]:focus,.button-group.clear .button[disabled]:hover{color:#1779ba}.button-group.clear .button:focus,.button-group.clear .button:hover{color:#0c3d5d}.button-group.clear .button.primary,.button-group.clear .button.primary.disabled,.button-group.clear .button.primary.disabled:focus,.button-group.clear .button.primary.disabled:hover,.button-group.clear .button.primary[disabled],.button-group.clear .button.primary[disabled]:focus,.button-group.clear .button.primary[disabled]:hover,.button-group.clear.primary .button,.button-group.clear.primary .button.disabled,.button-group.clear.primary .button.disabled:focus,.button-group.clear.primary .button.disabled:hover,.button-group.clear.primary .button[disabled],.button-group.clear.primary .button[disabled]:focus,.button-group.clear.primary .button[disabled]:hover{color:#1779ba}.button-group.clear .button.primary:focus,.button-group.clear .button.primary:hover,.button-group.clear.primary .button:focus,.button-group.clear.primary .button:hover{color:#0c3d5d}.button-group.clear .button.secondary,.button-group.clear .button.secondary.disabled,.button-group.clear .button.secondary.disabled:focus,.button-group.clear .button.secondary.disabled:hover,.button-group.clear .button.secondary[disabled],.button-group.clear .button.secondary[disabled]:focus,.button-group.clear .button.secondary[disabled]:hover,.button-group.clear.secondary .button,.button-group.clear.secondary .button.disabled,.button-group.clear.secondary .button.disabled:focus,.button-group.clear.secondary .button.disabled:hover,.button-group.clear.secondary .button[disabled],.button-group.clear.secondary .button[disabled]:focus,.button-group.clear.secondary .button[disabled]:hover{color:#767676}.button-group.clear .button.secondary:focus,.button-group.clear .button.secondary:hover,.button-group.clear.secondary .button:focus,.button-group.clear.secondary .button:hover{color:#3b3b3b}.button-group.clear .button.success,.button-group.clear .button.success.disabled,.button-group.clear .button.success.disabled:focus,.button-group.clear .button.success.disabled:hover,.button-group.clear .button.success[disabled],.button-group.clear .button.success[disabled]:focus,.button-group.clear .button.success[disabled]:hover,.button-group.clear.success .button,.button-group.clear.success .button.disabled,.button-group.clear.success .button.disabled:focus,.button-group.clear.success .button.disabled:hover,.button-group.clear.success .button[disabled],.button-group.clear.success .button[disabled]:focus,.button-group.clear.success .button[disabled]:hover{color:#3adb76}.button-group.clear .button.success:focus,.button-group.clear .button.success:hover,.button-group.clear.success .button:focus,.button-group.clear.success .button:hover{color:#157539}.button-group.clear .button.warning,.button-group.clear .button.warning.disabled,.button-group.clear .button.warning.disabled:focus,.button-group.clear .button.warning.disabled:hover,.button-group.clear .button.warning[disabled],.button-group.clear .button.warning[disabled]:focus,.button-group.clear .button.warning[disabled]:hover,.button-group.clear.warning .button,.button-group.clear.warning .button.disabled,.button-group.clear.warning .button.disabled:focus,.button-group.clear.warning .button.disabled:hover,.button-group.clear.warning .button[disabled],.button-group.clear.warning .button[disabled]:focus,.button-group.clear.warning .button[disabled]:hover{color:#ffae00}.button-group.clear .button.warning:focus,.button-group.clear .button.warning:hover,.button-group.clear.warning .button:focus,.button-group.clear.warning .button:hover{color:#805700}.button-group.clear .button.alert,.button-group.clear .button.alert.disabled,.button-group.clear .button.alert.disabled:focus,.button-group.clear .button.alert.disabled:hover,.button-group.clear .button.alert[disabled],.button-group.clear .button.alert[disabled]:focus,.button-group.clear .button.alert[disabled]:hover,.button-group.clear.alert .button,.button-group.clear.alert .button.disabled,.button-group.clear.alert .button.disabled:focus,.button-group.clear.alert .button.disabled:hover,.button-group.clear.alert .button[disabled],.button-group.clear.alert .button[disabled]:focus,.button-group.clear.alert .button[disabled]:hover{color:#cc4b37}.button-group.clear .button.alert:focus,.button-group.clear .button.alert:hover,.button-group.clear.alert .button:focus,.button-group.clear.alert .button:hover{color:#67251a}.button-group.no-gaps .button{margin-right:-.0625rem}.button-group.no-gaps .button+.button{border-left-color:transparent}.button-group.stacked,.button-group.stacked-for-medium,.button-group.stacked-for-small{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.button-group.stacked .button,.button-group.stacked-for-medium .button,.button-group.stacked-for-small .button{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%}.button-group.stacked .button:last-child,.button-group.stacked-for-medium .button:last-child,.button-group.stacked-for-small .button:last-child{margin-bottom:0}.button-group.stacked-for-medium.expanded .button,.button-group.stacked-for-small.expanded .button,.button-group.stacked.expanded .button{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}@media print,screen and (min-width:40em){.button-group.stacked-for-small .button{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;margin-bottom:0}}@media print,screen and (min-width:64em){.button-group.stacked-for-medium .button{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto;margin-bottom:0}}@media print,screen and (max-width:39.99875em){.button-group.stacked-for-small.expanded{display:block}.button-group.stacked-for-small.expanded .button{display:block;margin-right:0}}@media print,screen and (max-width:63.99875em){.button-group.stacked-for-medium.expanded{display:block}.button-group.stacked-for-medium.expanded .button{display:block;margin-right:0}}.close-button{color:#8a8a8a;cursor:pointer;position:absolute;z-index:10}[data-whatinput=mouse] .close-button{outline:0}.close-button:focus,.close-button:hover{color:#0a0a0a}.close-button.small{font-size:1.5em;line-height:1;right:.66rem;top:.33em}.close-button,.close-button.medium{font-size:2em;line-height:1;right:1rem;top:.5rem}.label{border-radius:0;cursor:default;display:inline-block;font-size:.8rem;line-height:1;padding:.33333rem .5rem;white-space:nowrap}.label,.label.primary{background:#1779ba;color:#fefefe}.label.secondary{background:#767676;color:#fefefe}.label.success{background:#3adb76;color:#0a0a0a}.label.warning{background:#ffae00;color:#0a0a0a}.label.alert{background:#cc4b37;color:#fefefe}.progress{background-color:#cacaca;border-radius:0;height:1rem;margin-bottom:1rem}.progress.primary .progress-meter{background-color:#1779ba}.progress.secondary .progress-meter{background-color:#767676}.progress.success .progress-meter{background-color:#3adb76}.progress.warning .progress-meter{background-color:#ffae00}.progress.alert .progress-meter{background-color:#cc4b37}.progress-meter{background-color:#1779ba;display:block;height:100%;position:relative;width:0}.progress-meter-text{color:#fefefe;font-size:.75rem;font-weight:700;left:50%;margin:0;position:absolute;top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);white-space:nowrap}.slider{background-color:#e6e6e6;cursor:pointer;height:.5rem;margin-bottom:2.25rem;margin-top:1.25rem;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.slider-fill{background-color:#cacaca;display:inline-block;height:.5rem;left:0;max-width:100%;position:absolute;top:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.slider-fill.is-dragging{-webkit-transition:all 0s linear;transition:all 0s linear}.slider-handle{background-color:#1779ba;border-radius:0;cursor:-webkit-grab;cursor:grab;display:inline-block;height:1.4rem;left:0;position:absolute;top:50%;-ms-touch-action:manipulation;touch-action:manipulation;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;width:1.4rem;z-index:1}[data-whatinput=mouse] .slider-handle{outline:0}.slider-handle:hover{background-color:#14679e}.slider-handle.is-dragging{cursor:-webkit-grabbing;cursor:grabbing;-webkit-transition:all 0s linear;transition:all 0s linear}.slider.disabled,.slider[disabled]{cursor:not-allowed;opacity:.25}.slider.vertical{display:inline-block;height:12.5rem;margin:0 1.25rem;-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1);width:.5rem}.slider.vertical .slider-fill{max-height:100%;top:0;width:.5rem}.slider.vertical .slider-handle{height:1.4rem;left:50%;position:absolute;top:0;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:1.4rem}.switch{color:#fefefe;font-size:.875rem;font-weight:700;height:2rem;margin-bottom:1rem;outline:0;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch-input{margin-bottom:0;opacity:0;position:absolute}.switch-paddle{background:#cacaca;border-radius:0;color:inherit;cursor:pointer;display:block;font-weight:inherit;height:2rem;position:relative;-webkit-transition:all .25s ease-out;transition:all .25s ease-out;width:4rem}input+.switch-paddle{margin:0}.switch-paddle:after{background:#fefefe;border-radius:0;content:"";display:block;height:1.5rem;left:.25rem;position:absolute;top:.25rem;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:all .25s ease-out;transition:all .25s ease-out;width:1.5rem}input:checked~.switch-paddle{background:#1779ba}input:checked~.switch-paddle:after{left:2.25rem}input:disabled~.switch-paddle{cursor:not-allowed;opacity:.5}[data-whatinput=mouse] input:focus~.switch-paddle{outline:0}.switch-active,.switch-inactive{position:absolute;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.switch-active{display:none;left:8%}input:checked+label>.switch-active{display:block}.switch-inactive{right:15%}input:checked+label>.switch-inactive{display:none}.switch.tiny{height:1.5rem}.switch.tiny .switch-paddle{font-size:.625rem;height:1.5rem;width:3rem}.switch.tiny .switch-paddle:after{height:1rem;left:.25rem;top:.25rem;width:1rem}.switch.tiny input:checked~.switch-paddle:after{left:1.75rem}.switch.small{height:1.75rem}.switch.small .switch-paddle{font-size:.75rem;height:1.75rem;width:3.5rem}.switch.small .switch-paddle:after{height:1.25rem;left:.25rem;top:.25rem;width:1.25rem}.switch.small input:checked~.switch-paddle:after{left:2rem}.switch.large{height:2.5rem}.switch.large .switch-paddle{font-size:1rem;height:2.5rem;width:5rem}.switch.large .switch-paddle:after{height:2rem;left:.25rem;top:.25rem;width:2rem}.switch.large input:checked~.switch-paddle:after{left:2.75rem}table{border-collapse:collapse;border-radius:0;margin-bottom:1rem;width:100%}tbody,tfoot,thead{background-color:#fefefe;border:1px solid #f1f1f1}caption{font-weight:700;padding:.5rem .625rem .625rem}thead{background:#f8f8f8}tfoot,thead{color:#0a0a0a}tfoot{background:#f1f1f1}tfoot tr,thead tr{background:0 0}tfoot td,tfoot th,thead td,thead th{font-weight:700;padding:.5rem .625rem .625rem;text-align:left}tbody td,tbody th{padding:.5rem .625rem .625rem}tbody tr:nth-child(2n){background-color:#f1f1f1;border-bottom:0}table.unstriped tbody{background-color:#fefefe}table.unstriped tbody tr{background-color:#fefefe;border-bottom:1px solid #f1f1f1}@media print,screen and (max-width:63.99875em){table.stack tfoot,table.stack thead{display:none}table.stack td,table.stack th,table.stack tr{display:block}table.stack td{border-top:0}}table.scroll{display:block;overflow-x:auto;width:100%}table.hover thead tr:hover{background-color:#f3f3f3}table.hover tfoot tr:hover{background-color:#ececec}table.hover tbody tr:hover{background-color:#f9f9f9}table.hover:not(.unstriped) tr:nth-of-type(2n):hover{background-color:#ececec}.table-scroll{overflow-x:auto}.badge{border-radius:50%;display:inline-block;font-size:.6rem;min-width:2.1em;padding:.3em;text-align:center}.badge,.badge.primary{background:#1779ba;color:#fefefe}.badge.secondary{background:#767676;color:#fefefe}.badge.success{background:#3adb76;color:#0a0a0a}.badge.warning{background:#ffae00;color:#0a0a0a}.badge.alert{background:#cc4b37;color:#fefefe}.breadcrumbs{list-style:none;margin:0 0 1rem}.breadcrumbs:after,.breadcrumbs:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.breadcrumbs:after{clear:both}.breadcrumbs li{color:#0a0a0a;cursor:default;float:left;font-size:.6875rem;text-transform:uppercase}.breadcrumbs li:not(:last-child):after{color:#cacaca;content:"/";margin:0 .75rem;opacity:1;position:relative}.breadcrumbs a{color:#1779ba}.breadcrumbs a:hover{text-decoration:underline}.breadcrumbs .disabled{color:#cacaca;cursor:not-allowed}.callout{background-color:#fff;border:1px solid hsla(0,0%,4%,.25);border-radius:0;color:#0a0a0a;margin:0 0 1rem;padding:1rem;position:relative}.callout>:first-child{margin-top:0}.callout>:last-child{margin-bottom:0}.callout.primary{background-color:#d7ecfa;color:#0a0a0a}.callout.secondary{background-color:#eaeaea;color:#0a0a0a}.callout.success{background-color:#e1faea;color:#0a0a0a}.callout.warning{background-color:#fff3d9;color:#0a0a0a}.callout.alert{background-color:#f7e4e1;color:#0a0a0a}.callout.small{padding:.5rem}.callout.large{padding:3rem}.card{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-box-flex:1;-ms-flex-positive:1;background:#fefefe;border:1px solid #e6e6e6;border-radius:0;-webkit-box-shadow:none;box-shadow:none;color:#0a0a0a;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-grow:1;flex-grow:1;margin-bottom:1rem;overflow:hidden}.card>:last-child{margin-bottom:0}.card-divider{-webkit-box-flex:0;background:#e6e6e6;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;padding:1rem}.card-divider>:last-child{margin-bottom:0}.card-section{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto;padding:1rem}.card-section>:last-child{margin-bottom:0}.card-image{min-height:1px}.dropdown-pane{background-color:#fefefe;border:1px solid #cacaca;border-radius:0;display:none;font-size:1rem;padding:1rem;position:absolute;visibility:hidden;width:300px;z-index:10}.dropdown-pane.is-opening{display:block}.dropdown-pane.is-open{display:block;visibility:visible}.dropdown-pane.tiny{width:100px}.dropdown-pane.small{width:200px}.dropdown-pane.large{width:400px}.pagination{margin-bottom:1rem;margin-left:0}.pagination:after,.pagination:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.pagination:after{clear:both}.pagination li{border-radius:0;display:none;font-size:.875rem;margin-right:.0625rem}.pagination li:first-child,.pagination li:last-child{display:inline-block}@media print,screen and (min-width:40em){.pagination li{display:inline-block}}.pagination a,.pagination button{border-radius:0;color:#0a0a0a;display:block;padding:.1875rem .625rem}.pagination a:hover,.pagination button:hover{background:#e6e6e6}.pagination .current{background:#1779ba;color:#fefefe;cursor:default;padding:.1875rem .625rem}.pagination .disabled{color:#cacaca;cursor:not-allowed;padding:.1875rem .625rem}.pagination .disabled:hover{background:0 0}.pagination .ellipsis:after{color:#0a0a0a;content:"…";padding:.1875rem .625rem}.pagination-previous a:before,.pagination-previous.disabled:before{content:"«";display:inline-block;margin-right:.5rem}.pagination-next a:after,.pagination-next.disabled:after{content:"»";display:inline-block;margin-left:.5rem}.has-tip{border-bottom:1px dotted #8a8a8a;cursor:help;display:inline-block;font-weight:700;position:relative}.tooltip{background-color:#0a0a0a;border-radius:0;color:#fefefe;font-size:80%;max-width:10rem;padding:.75rem;top:calc(100% + .6495rem);z-index:1200}.tooltip,.tooltip:before{position:absolute}.tooltip.bottom:before{border-color:transparent transparent #0a0a0a;border-style:solid;border-width:0 .75rem .75rem;bottom:100%;content:"";display:block;height:0;width:0}.tooltip.bottom.align-center:before{left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.tooltip.top:before{border-color:#0a0a0a transparent transparent;border-style:solid;border-width:.75rem .75rem 0;bottom:auto;content:"";display:block;height:0;top:100%;width:0}.tooltip.top.align-center:before{left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.tooltip.left:before{border-color:transparent transparent transparent #0a0a0a;border-style:solid;border-width:.75rem 0 .75rem .75rem;content:"";display:block;height:0;left:100%;width:0}.tooltip.left.align-center:before{bottom:auto;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.tooltip.right:before{border-color:transparent #0a0a0a transparent transparent;border-style:solid;border-width:.75rem .75rem .75rem 0;content:"";display:block;height:0;left:auto;right:100%;width:0}.tooltip.right.align-center:before{bottom:auto;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.tooltip.align-top:before{bottom:auto;top:10%}.tooltip.align-bottom:before{bottom:10%;top:auto}.tooltip.align-left:before{left:10%;right:auto}.tooltip.align-right:before{left:auto;right:10%}.accordion{background:#fefefe;list-style-type:none;margin-left:0}.accordion[disabled] .accordion-title{cursor:not-allowed}.accordion-item:first-child>:first-child,.accordion-item:last-child>:last-child{border-radius:0}.accordion-title{border:1px solid #e6e6e6;border-bottom:0;color:#1779ba;display:block;font-size:.75rem;line-height:1;padding:1.25rem 1rem;position:relative}:last-child:not(.is-active)>.accordion-title{border-bottom:1px solid #e6e6e6;border-radius:0}.accordion-title:focus,.accordion-title:hover{background-color:#e6e6e6}.accordion-title:before{content:"+";margin-top:-.5rem;position:absolute;right:1rem;top:50%}.is-active>.accordion-title:before{content:"–"}.accordion-content{background-color:#fefefe;border:1px solid #e6e6e6;border-bottom:0;color:#0a0a0a;display:none;padding:1rem}:last-child>.accordion-content:last-child{border-bottom:1px solid #e6e6e6}.media-object{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;margin-bottom:1rem}.media-object img{max-width:none}@media print,screen and (max-width:39.99875em){.media-object.stack-for-small{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}}.media-object-section{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.media-object-section:first-child{padding-right:1rem}.media-object-section:last-child:not(:nth-child(2)){padding-left:1rem}.media-object-section>:last-child{margin-bottom:0}@media print,screen and (max-width:39.99875em){.stack-for-small .media-object-section{-ms-flex-preferred-size:100%;-webkit-flex-basis:100%;flex-basis:100%;max-width:100%;padding:0 0 1rem}.stack-for-small .media-object-section img{width:100%}}.media-object-section.main-section{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}.orbit,.orbit-container{position:relative}.orbit-container{height:0;list-style:none;margin:0;overflow:hidden}.orbit-slide{position:absolute;width:100%}.orbit-slide.no-motionui.is-active{left:0;top:0}.orbit-figure{margin:0}.orbit-image{margin:0;max-width:100%;width:100%}.orbit-caption{background-color:hsla(0,0%,4%,.5);bottom:0;margin-bottom:0;width:100%}.orbit-caption,.orbit-next,.orbit-previous{color:#fefefe;padding:1rem;position:absolute}.orbit-next,.orbit-previous{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);z-index:10}[data-whatinput=mouse] .orbit-next,[data-whatinput=mouse] .orbit-previous{outline:0}.orbit-next:active,.orbit-next:focus,.orbit-next:hover,.orbit-previous:active,.orbit-previous:focus,.orbit-previous:hover{background-color:hsla(0,0%,4%,.5)}.orbit-previous{left:0}.orbit-next{left:auto;right:0}.orbit-bullets{margin-bottom:.8rem;margin-top:.8rem;position:relative;text-align:center}[data-whatinput=mouse] .orbit-bullets{outline:0}.orbit-bullets button{background-color:#cacaca;border-radius:50%;height:1.2rem;margin:.1rem;width:1.2rem}.orbit-bullets button.is-active,.orbit-bullets button:hover{background-color:#8a8a8a}.flex-video,.responsive-embed{height:0;margin-bottom:1rem;overflow:hidden;padding-bottom:75%;position:relative}.flex-video embed,.flex-video iframe,.flex-video object,.flex-video video,.responsive-embed embed,.responsive-embed iframe,.responsive-embed object,.responsive-embed video{height:100%;left:0;position:absolute;top:0;width:100%}.flex-video.widescreen,.responsive-embed.widescreen{padding-bottom:56.25%}.tabs{background:#fefefe;border:1px solid #e6e6e6;list-style-type:none;margin:0}.tabs:after,.tabs:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.tabs:after{clear:both}.tabs.vertical>li{display:block;float:none;width:auto}.tabs.simple>li>a{padding:0}.tabs.simple>li>a:hover{background:0 0}.tabs.primary{background:#1779ba}.tabs.primary>li>a{color:#fefefe}.tabs.primary>li>a:focus,.tabs.primary>li>a:hover{background:#1673b1}.tabs-title{float:left}.tabs-title>a{color:#1779ba;display:block;font-size:.75rem;line-height:1;padding:1.25rem 1.5rem}[data-whatinput=mouse] .tabs-title>a{outline:0}.tabs-title>a:hover{background:#fefefe;color:#1468a0}.tabs-title>a:focus,.tabs-title>a[aria-selected=true]{background:#e6e6e6;color:#1779ba}.tabs-content{background:#fefefe;border:1px solid #e6e6e6;border-top:0;color:#0a0a0a;-webkit-transition:all .5s ease;transition:all .5s ease}.tabs-content.vertical{border:1px solid #e6e6e6;border-left:0}.tabs-panel{display:none;padding:1rem}.tabs-panel.is-active{display:block}.thumbnail{border:4px solid #fefefe;border-radius:0;-webkit-box-shadow:0 0 0 1px hsla(0,0%,4%,.2);box-shadow:0 0 0 1px hsla(0,0%,4%,.2);display:inline-block;line-height:0;margin-bottom:1rem;max-width:100%}a.thumbnail{-webkit-transition:-webkit-box-shadow .2s ease-out;transition:-webkit-box-shadow .2s ease-out;transition:box-shadow .2s ease-out;transition:box-shadow .2s ease-out,-webkit-box-shadow .2s ease-out}a.thumbnail:focus,a.thumbnail:hover{-webkit-box-shadow:0 0 6px 1px rgba(23,121,186,.5);box-shadow:0 0 6px 1px rgba(23,121,186,.5)}a.thumbnail image{-webkit-box-shadow:none;box-shadow:none}.menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;list-style:none;margin:0;padding:0;position:relative}[data-whatinput=mouse] .menu li{outline:0}.menu .button,.menu a{display:block;line-height:1;padding:.7rem 1rem;text-decoration:none}.menu a,.menu button,.menu input,.menu select{margin-bottom:0}.menu input{display:inline-block}.menu,.menu.horizontal{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.menu.vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.menu.vertical.icon-bottom li a i,.menu.vertical.icon-bottom li a img,.menu.vertical.icon-bottom li a svg,.menu.vertical.icon-top li a i,.menu.vertical.icon-top li a img,.menu.vertical.icon-top li a svg{text-align:left}.menu.expanded li{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}.menu.expanded.icon-bottom li a i,.menu.expanded.icon-bottom li a img,.menu.expanded.icon-bottom li a svg,.menu.expanded.icon-top li a i,.menu.expanded.icon-top li a img,.menu.expanded.icon-top li a svg{text-align:left}.menu.simple{-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center}.menu.simple li+li{margin-left:1rem}.menu.simple a{padding:0}@media print,screen and (min-width:40em){.menu.medium-horizontal{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.menu.medium-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.menu.medium-expanded li,.menu.medium-simple li{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}}@media print,screen and (min-width:64em){.menu.large-horizontal{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.menu.large-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.menu.large-expanded li,.menu.large-simple li{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}}.menu.nested{margin-left:1rem;margin-right:0}.menu.icon-bottom a,.menu.icon-left a,.menu.icon-right a,.menu.icon-top a,.menu.icons a{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.menu.icon-left li a,.menu.nested.icon-left li a{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap}.menu.icon-left li a i,.menu.icon-left li a img,.menu.icon-left li a svg,.menu.nested.icon-left li a i,.menu.nested.icon-left li a img,.menu.nested.icon-left li a svg{margin-right:.25rem}.menu.icon-right li a,.menu.nested.icon-right li a{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-flow:row nowrap;-ms-flex-flow:row nowrap;flex-flow:row nowrap}.menu.icon-right li a i,.menu.icon-right li a img,.menu.icon-right li a svg,.menu.nested.icon-right li a i,.menu.nested.icon-right li a img,.menu.nested.icon-right li a svg{margin-left:.25rem}.menu.icon-top li a,.menu.nested.icon-top li a{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-flow:column nowrap;-ms-flex-flow:column nowrap;flex-flow:column nowrap}.menu.icon-top li a i,.menu.icon-top li a img,.menu.icon-top li a svg,.menu.nested.icon-top li a i,.menu.nested.icon-top li a img,.menu.nested.icon-top li a svg{-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;margin-bottom:.25rem;text-align:center}.menu.icon-bottom li a,.menu.nested.icon-bottom li a{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-flow:column nowrap;-ms-flex-flow:column nowrap;flex-flow:column nowrap}.menu.icon-bottom li a i,.menu.icon-bottom li a img,.menu.icon-bottom li a svg,.menu.nested.icon-bottom li a i,.menu.nested.icon-bottom li a img,.menu.nested.icon-bottom li a svg{-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch;margin-bottom:.25rem;text-align:center}.menu .active>a,.menu .is-active>a{background:#1779ba;color:#fefefe}.menu.align-left{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.menu.align-right li{-webkit-box-pack:end;-ms-flex-pack:end;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:flex-end;justify-content:flex-end}.menu.align-right li .submenu li{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.menu.align-right.vertical li{display:block;text-align:right}.menu.align-right.icon-bottom li a i,.menu.align-right.icon-bottom li a img,.menu.align-right.icon-bottom li a svg,.menu.align-right.icon-top li a i,.menu.align-right.icon-top li a img,.menu.align-right.icon-top li a svg,.menu.align-right.vertical li .submenu li{text-align:right}.menu.align-right .nested{margin-left:0;margin-right:1rem}.menu.align-center li{-webkit-box-pack:center;-ms-flex-pack:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;justify-content:center}.menu.align-center li .submenu li{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.menu .menu-text{color:inherit;font-weight:700;line-height:1;padding:.7rem 1rem}.menu-centered>.menu,.menu-centered>.menu li{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center}.menu-centered>.menu li{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.menu-centered>.menu li .submenu li{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.no-js [data-responsive-menu] ul{display:none}.menu-icon{cursor:pointer;display:inline-block;height:16px;position:relative;vertical-align:middle;width:20px}.menu-icon:after{background:#fefefe;-webkit-box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe;box-shadow:0 7px 0 #fefefe,0 14px 0 #fefefe;content:"";display:block;height:2px;left:0;position:absolute;top:0;width:100%}.menu-icon:hover:after{background:#cacaca;-webkit-box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca;box-shadow:0 7px 0 #cacaca,0 14px 0 #cacaca}.menu-icon.dark{cursor:pointer;display:inline-block;height:16px;position:relative;vertical-align:middle;width:20px}.menu-icon.dark:after{background:#0a0a0a;-webkit-box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a;box-shadow:0 7px 0 #0a0a0a,0 14px 0 #0a0a0a;content:"";display:block;height:2px;left:0;position:absolute;top:0;width:100%}.menu-icon.dark:hover:after{background:#8a8a8a;-webkit-box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a;box-shadow:0 7px 0 #8a8a8a,0 14px 0 #8a8a8a}.accordion-menu li{width:100%}.accordion-menu .is-accordion-submenu a,.accordion-menu a{padding:.7rem 1rem}.accordion-menu .nested.is-accordion-submenu{margin-left:1rem;margin-right:0}.accordion-menu.align-right .nested.is-accordion-submenu{margin-left:0;margin-right:1rem}.accordion-menu .is-accordion-submenu-parent:not(.has-submenu-toggle)>a{position:relative}.accordion-menu .is-accordion-submenu-parent:not(.has-submenu-toggle)>a:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;content:"";display:block;height:0;margin-top:-3px;position:absolute;right:1rem;top:50%;width:0}.accordion-menu.align-left .is-accordion-submenu-parent>a:after{left:auto;right:1rem}.accordion-menu.align-right .is-accordion-submenu-parent>a:after{left:1rem;right:auto}.accordion-menu .is-accordion-submenu-parent[aria-expanded=true]>a:after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg);-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.is-accordion-submenu-parent{position:relative}.has-submenu-toggle>a{margin-right:40px}.submenu-toggle{cursor:pointer;height:40px;position:absolute;right:0;top:0;width:40px}.submenu-toggle:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;bottom:0;content:"";display:block;height:0;margin:auto;top:0;width:0}.submenu-toggle[aria-expanded=true]:after{-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1);-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.submenu-toggle-text{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.is-drilldown{overflow:hidden;position:relative}.is-drilldown li{display:block}.is-drilldown.animate-height{-webkit-transition:height .5s;transition:height .5s}.drilldown a{background:#fefefe;padding:.7rem 1rem}.drilldown .is-drilldown-submenu{background:#fefefe;left:100%;position:absolute;top:0;-webkit-transition:-webkit-transform .15s linear;transition:-webkit-transform .15s linear;transition:transform .15s linear;transition:transform .15s linear,-webkit-transform .15s linear;width:100%;z-index:-1}.drilldown .is-drilldown-submenu.is-active{display:block;-webkit-transform:translateX(-100%);-ms-transform:translateX(-100%);transform:translateX(-100%);z-index:1}.drilldown .is-drilldown-submenu.is-closing{-webkit-transform:translateX(100%);-ms-transform:translateX(100%);transform:translateX(100%)}.drilldown .is-drilldown-submenu a{padding:.7rem 1rem}.drilldown .nested.is-drilldown-submenu{margin-left:0;margin-right:0}.drilldown .drilldown-submenu-cover-previous{min-height:100%}.drilldown .is-drilldown-submenu-parent>a{position:relative}.drilldown .is-drilldown-submenu-parent>a:after{margin-top:-6px;position:absolute;top:50%}.drilldown .is-drilldown-submenu-parent>a:after,.drilldown.align-left .is-drilldown-submenu-parent>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;right:1rem;width:0}.drilldown.align-left .is-drilldown-submenu-parent>a:after{left:auto}.drilldown.align-right .is-drilldown-submenu-parent>a:after{left:1rem;right:auto}.drilldown .js-drilldown-back>a:before,.drilldown.align-right .is-drilldown-submenu-parent>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;width:0}.drilldown .js-drilldown-back>a:before{display:inline-block;margin-right:.75rem;vertical-align:middle}.dropdown.menu>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu>li.opens-right>.is-dropdown-submenu{left:0;right:auto;top:100%}.dropdown.menu>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu>li.is-dropdown-submenu-parent>a:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;content:"";display:block;height:0;left:auto;margin-top:-3px;right:5px;width:0}[data-whatinput=mouse] .dropdown.menu a{outline:0}.dropdown.menu>li>a{padding:.7rem 1rem}.dropdown.menu>li.is-active>a{background:0 0;color:#1779ba}.no-js .dropdown.menu ul{display:none}.dropdown.menu .nested.is-dropdown-submenu{margin-left:0;margin-right:0}.dropdown.menu.vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%;top:0}.dropdown.menu.vertical>li.opens-right>.is-dropdown-submenu{left:100%;right:auto}.dropdown.menu.vertical>li>a:after{right:14px}.dropdown.menu.vertical>li.opens-left>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;left:5px;right:auto;width:0}.dropdown.menu.vertical>li.opens-right>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;width:0}@media print,screen and (min-width:40em){.dropdown.menu.medium-horizontal>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu.medium-horizontal>li.opens-right>.is-dropdown-submenu{left:0;right:auto;top:100%}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu.medium-horizontal>li.is-dropdown-submenu-parent>a:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;content:"";display:block;height:0;left:auto;margin-top:-3px;right:5px;width:0}.dropdown.menu.medium-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.medium-vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%;top:0}.dropdown.menu.medium-vertical>li.opens-right>.is-dropdown-submenu{left:100%;right:auto}.dropdown.menu.medium-vertical>li>a:after{right:14px}.dropdown.menu.medium-vertical>li.opens-left>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;left:5px;right:auto;width:0}.dropdown.menu.medium-vertical>li.opens-right>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;width:0}}@media print,screen and (min-width:64em){.dropdown.menu.large-horizontal>li.opens-left>.is-dropdown-submenu{left:auto;right:0;top:100%}.dropdown.menu.large-horizontal>li.opens-right>.is-dropdown-submenu{left:0;right:auto;top:100%}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a{padding-right:1.5rem;position:relative}.dropdown.menu.large-horizontal>li.is-dropdown-submenu-parent>a:after{border-color:#1779ba transparent transparent;border-style:solid;border-width:6px 6px 0;content:"";display:block;height:0;left:auto;margin-top:-3px;right:5px;width:0}.dropdown.menu.large-vertical>li .is-dropdown-submenu{top:0}.dropdown.menu.large-vertical>li.opens-left>.is-dropdown-submenu{left:auto;right:100%;top:0}.dropdown.menu.large-vertical>li.opens-right>.is-dropdown-submenu{left:100%;right:auto}.dropdown.menu.large-vertical>li>a:after{right:14px}.dropdown.menu.large-vertical>li.opens-left>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;left:5px;right:auto;width:0}.dropdown.menu.large-vertical>li.opens-right>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;width:0}}.dropdown.menu.align-right .is-dropdown-submenu.first-sub{left:auto;right:0;top:100%}.is-dropdown-menu.vertical{width:100px}.is-dropdown-menu.vertical.align-right{float:right}.is-dropdown-submenu-parent{position:relative}.is-dropdown-submenu-parent a:after{left:auto;margin-top:-6px;position:absolute;right:5px;top:50%}.is-dropdown-submenu-parent.opens-inner>.is-dropdown-submenu{left:auto;top:100%}.is-dropdown-submenu-parent.opens-left>.is-dropdown-submenu{left:auto;right:100%}.is-dropdown-submenu-parent.opens-right>.is-dropdown-submenu{left:100%;right:auto}.is-dropdown-submenu{background:#fefefe;border:1px solid #cacaca;display:none;left:100%;min-width:200px;position:absolute;top:0;z-index:1}.dropdown .is-dropdown-submenu a{padding:.7rem 1rem}.is-dropdown-submenu .is-dropdown-submenu-parent>a:after{right:14px}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-left>a:after{border-color:transparent #1779ba transparent transparent;border-style:solid;border-width:6px 6px 6px 0;content:"";display:block;height:0;left:5px;right:auto;width:0}.is-dropdown-submenu .is-dropdown-submenu-parent.opens-right>a:after{border-color:transparent transparent transparent #1779ba;border-style:solid;border-width:6px 0 6px 6px;content:"";display:block;height:0;width:0}.is-dropdown-submenu .is-dropdown-submenu{margin-top:-1px}.is-dropdown-submenu>li{width:100%}.is-dropdown-submenu.js-dropdown-active{display:block}.is-off-canvas-open{overflow:hidden}.js-off-canvas-overlay{background:hsla(0,0%,100%,.25);height:100%;left:0;opacity:0;overflow:hidden;position:absolute;top:0;-webkit-transition:opacity .5s ease,visibility .5s ease;transition:opacity .5s ease,visibility .5s ease;visibility:hidden;width:100%;z-index:11}.js-off-canvas-overlay.is-visible{opacity:1;visibility:visible}.js-off-canvas-overlay.is-closable{cursor:pointer}.js-off-canvas-overlay.is-overlay-absolute{position:absolute}.js-off-canvas-overlay.is-overlay-fixed{position:fixed}.off-canvas-wrapper{overflow:hidden;position:relative}.off-canvas{-webkit-backface-visibility:hidden;backface-visibility:hidden;background:#e6e6e6;position:fixed;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:12}[data-whatinput=mouse] .off-canvas{outline:0}.off-canvas.is-transition-push{z-index:12}.off-canvas.is-closed{visibility:hidden}.off-canvas.is-transition-overlap{z-index:13}.off-canvas.is-transition-overlap.is-open{-webkit-box-shadow:0 0 10px hsla(0,0%,4%,.7);box-shadow:0 0 10px hsla(0,0%,4%,.7)}.off-canvas.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-absolute{-webkit-backface-visibility:hidden;backface-visibility:hidden;background:#e6e6e6;position:absolute;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease;z-index:12}[data-whatinput=mouse] .off-canvas-absolute{outline:0}.off-canvas-absolute.is-transition-push{z-index:12}.off-canvas-absolute.is-closed{visibility:hidden}.off-canvas-absolute.is-transition-overlap{z-index:13}.off-canvas-absolute.is-transition-overlap.is-open{-webkit-box-shadow:0 0 10px hsla(0,0%,4%,.7);box-shadow:0 0 10px hsla(0,0%,4%,.7)}.off-canvas-absolute.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.position-left{-webkit-overflow-scrolling:touch;height:100%;left:0;overflow-y:auto;top:0;width:250px}.off-canvas-content .off-canvas.position-left,.position-left{-webkit-transform:translateX(-250px);-ms-transform:translateX(-250px);transform:translateX(-250px)}.off-canvas-content .off-canvas.position-left.is-transition-overlap.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-content.is-open-left.has-transition-push{-webkit-transform:translateX(250px);-ms-transform:translateX(250px);transform:translateX(250px)}.position-left.is-transition-push{-webkit-box-shadow:inset -13px 0 20px -13px hsla(0,0%,4%,.25);box-shadow:inset -13px 0 20px -13px hsla(0,0%,4%,.25)}.position-right{-webkit-overflow-scrolling:touch;height:100%;overflow-y:auto;right:0;top:0;width:250px}.off-canvas-content .off-canvas.position-right,.position-right{-webkit-transform:translateX(250px);-ms-transform:translateX(250px);transform:translateX(250px)}.off-canvas-content .off-canvas.position-right.is-transition-overlap.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-content.is-open-right.has-transition-push{-webkit-transform:translateX(-250px);-ms-transform:translateX(-250px);transform:translateX(-250px)}.position-right.is-transition-push{-webkit-box-shadow:inset 13px 0 20px -13px hsla(0,0%,4%,.25);box-shadow:inset 13px 0 20px -13px hsla(0,0%,4%,.25)}.position-top{-webkit-overflow-scrolling:touch;height:250px;left:0;overflow-x:auto;top:0;width:100%}.off-canvas-content .off-canvas.position-top,.position-top{-webkit-transform:translateY(-250px);-ms-transform:translateY(-250px);transform:translateY(-250px)}.off-canvas-content .off-canvas.position-top.is-transition-overlap.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-content.is-open-top.has-transition-push{-webkit-transform:translateY(250px);-ms-transform:translateY(250px);transform:translateY(250px)}.position-top.is-transition-push{-webkit-box-shadow:inset 0 -13px 20px -13px hsla(0,0%,4%,.25);box-shadow:inset 0 -13px 20px -13px hsla(0,0%,4%,.25)}.position-bottom{-webkit-overflow-scrolling:touch;bottom:0;height:250px;left:0;overflow-x:auto;width:100%}.off-canvas-content .off-canvas.position-bottom,.position-bottom{-webkit-transform:translateY(250px);-ms-transform:translateY(250px);transform:translateY(250px)}.off-canvas-content .off-canvas.position-bottom.is-transition-overlap.is-open{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}.off-canvas-content.is-open-bottom.has-transition-push{-webkit-transform:translateY(-250px);-ms-transform:translateY(-250px);transform:translateY(-250px)}.position-bottom.is-transition-push{-webkit-box-shadow:inset 0 13px 20px -13px hsla(0,0%,4%,.25);box-shadow:inset 0 13px 20px -13px hsla(0,0%,4%,.25)}.off-canvas-content{-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-transition-overlap,.off-canvas-content.has-transition-push{-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease;transition:transform .5s ease,-webkit-transform .5s ease}.off-canvas-content .off-canvas.is-open,.off-canvas-content.has-transition-push{-webkit-transform:translate(0);-ms-transform:translate(0);transform:translate(0)}@media print,screen and (min-width:40em){.position-left.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-left.reveal-for-medium .close-button{display:none}.off-canvas-content .position-left.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-left,.position-left.reveal-for-medium~.off-canvas-content{margin-left:250px}.position-right.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-right.reveal-for-medium .close-button{display:none}.off-canvas-content .position-right.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-right,.position-right.reveal-for-medium~.off-canvas-content{margin-right:250px}.position-top.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-top.reveal-for-medium .close-button{display:none}.off-canvas-content .position-top.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-top,.position-top.reveal-for-medium~.off-canvas-content{margin-top:250px}.position-bottom.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-bottom.reveal-for-medium .close-button{display:none}.off-canvas-content .position-bottom.reveal-for-medium{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-bottom,.position-bottom.reveal-for-medium~.off-canvas-content{margin-bottom:250px}}@media print,screen and (min-width:64em){.position-left.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-left.reveal-for-large .close-button{display:none}.off-canvas-content .position-left.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-left,.position-left.reveal-for-large~.off-canvas-content{margin-left:250px}.position-right.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-right.reveal-for-large .close-button{display:none}.off-canvas-content .position-right.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-right,.position-right.reveal-for-large~.off-canvas-content{margin-right:250px}.position-top.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-top.reveal-for-large .close-button{display:none}.off-canvas-content .position-top.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-top,.position-top.reveal-for-large~.off-canvas-content{margin-top:250px}.position-bottom.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none;-webkit-transition:none;transition:none;visibility:visible;z-index:12}.position-bottom.reveal-for-large .close-button{display:none}.off-canvas-content .position-bottom.reveal-for-large{-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas-content.has-reveal-bottom,.position-bottom.reveal-for-large~.off-canvas-content{margin-bottom:250px}}@media print,screen and (min-width:40em){.off-canvas.in-canvas-for-medium{background:0 0;height:auto;overflow:visible;position:static;-webkit-transition:none;transition:none;visibility:visible;width:auto}.off-canvas.in-canvas-for-medium.position-bottom,.off-canvas.in-canvas-for-medium.position-left,.off-canvas.in-canvas-for-medium.position-right,.off-canvas.in-canvas-for-medium.position-top{-webkit-box-shadow:none;box-shadow:none;-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas.in-canvas-for-medium .close-button{display:none}}@media print,screen and (min-width:64em){.off-canvas.in-canvas-for-large{background:0 0;height:auto;overflow:visible;position:static;-webkit-transition:none;transition:none;visibility:visible;width:auto}.off-canvas.in-canvas-for-large.position-bottom,.off-canvas.in-canvas-for-large.position-left,.off-canvas.in-canvas-for-large.position-right,.off-canvas.in-canvas-for-large.position-top{-webkit-box-shadow:none;box-shadow:none;-webkit-transform:none;-ms-transform:none;transform:none}.off-canvas.in-canvas-for-large .close-button{display:none}}html.is-reveal-open{overflow-y:hidden;position:fixed;width:100%}html.is-reveal-open.zf-has-scroll{-webkit-overflow-scrolling:touch;overflow-y:scroll}html.is-reveal-open body{overflow-y:hidden}.reveal-overlay{background-color:hsla(0,0%,4%,.45);bottom:0;left:0;position:fixed;right:0;top:0;z-index:1005}.reveal,.reveal-overlay{-webkit-overflow-scrolling:touch;display:none;overflow-y:auto}.reveal{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:#fefefe;border:1px solid #cacaca;border-radius:0;margin-left:auto;margin-right:auto;padding:1rem;position:relative;top:100px;z-index:1006}[data-whatinput=mouse] .reveal{outline:0}@media print,screen and (min-width:40em){.reveal{min-height:0}}.reveal .column{min-width:0}.reveal>:last-child{margin-bottom:0}@media print,screen and (min-width:40em){.reveal{max-width:75rem;width:600px}}.reveal.collapse{padding:0}@media print,screen and (min-width:40em){.reveal.tiny{max-width:75rem;width:30%}.reveal.small{max-width:75rem;width:50%}.reveal.large{max-width:75rem;width:90%}}.reveal.full{border:0;border-radius:0;bottom:0;height:100%;left:0;margin-left:0;max-width:none;min-height:100%;right:0;top:0;width:100%}@media print,screen and (max-width:39.99875em){.reveal{border:0;border-radius:0;bottom:0;height:100%;left:0;margin-left:0;max-width:none;min-height:100%;right:0;top:0;width:100%}}.reveal.without-overlay{position:fixed}.sticky,.sticky-container{position:relative}.sticky{-webkit-transform:translateZ(0);transform:translateZ(0);z-index:0}.sticky.is-stuck{position:fixed;width:100%;z-index:5}.sticky.is-stuck.is-at-top{top:0}.sticky.is-stuck.is-at-bottom{bottom:0}.sticky.is-anchored{left:auto;position:relative;right:auto}.sticky.is-anchored.is-at-bottom{bottom:0}.title-bar{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;background:#0a0a0a;color:#fefefe;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:flex-start;justify-content:flex-start;padding:.5rem}.title-bar .menu-icon{margin-left:.25rem;margin-right:.25rem}.title-bar-left,.title-bar-right{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}.title-bar-right{text-align:right}.title-bar-title{display:inline-block;font-weight:700;vertical-align:middle}.top-bar{-webkit-box-pack:justify;-ms-flex-pack:justify;-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-justify-content:space-between;justify-content:space-between;padding:.5rem}.top-bar,.top-bar ul{background-color:#e6e6e6}.top-bar input{margin-right:1rem;max-width:200px}.top-bar .input-group-field{margin-right:0;width:100%}.top-bar input.button{width:auto}.top-bar .top-bar-left,.top-bar .top-bar-right{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}@media print,screen and (min-width:40em){.top-bar{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.top-bar .top-bar-left{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;margin-right:auto}.top-bar .top-bar-right{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;margin-left:auto}}@media print,screen and (max-width:63.99875em){.top-bar.stacked-for-medium{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.top-bar.stacked-for-medium .top-bar-left,.top-bar.stacked-for-medium .top-bar-right{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}@media print,screen and (max-width:74.99875em){.top-bar.stacked-for-large{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.top-bar.stacked-for-large .top-bar-left,.top-bar.stacked-for-large .top-bar-right{-webkit-box-flex:0;-webkit-flex:0 0 100%;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}.top-bar-title{margin:.5rem 1rem .5rem 0}.top-bar-left,.top-bar-right,.top-bar-title{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}.float-left{float:left!important}.float-right{float:right!important}.float-center{display:block;margin-left:auto;margin-right:auto}.clearfix:after,.clearfix:before{-ms-flex-preferred-size:0;-webkit-box-ordinal-group:2;-ms-flex-order:1;content:" ";display:table;-webkit-flex-basis:0;flex-basis:0;-webkit-order:1;order:1}.clearfix:after{clear:both}.align-left{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.align-right{-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end}.align-center{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center}.align-justify{-webkit-box-pack:justify;-ms-flex-pack:justify;-webkit-justify-content:space-between;justify-content:space-between}.align-spaced{-ms-flex-pack:distribute;-webkit-justify-content:space-around;justify-content:space-around}.align-left.vertical.menu>li>a{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start}.align-right.vertical.menu>li>a{-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end}.align-center.vertical.menu>li>a{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center}.align-top{-webkit-box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;align-items:flex-start}.align-self-top{-ms-flex-item-align:start;-webkit-align-self:flex-start;align-self:flex-start}.align-bottom{-webkit-box-align:end;-ms-flex-align:end;-webkit-align-items:flex-end;align-items:flex-end}.align-self-bottom{-ms-flex-item-align:end;-webkit-align-self:flex-end;align-self:flex-end}.align-middle{-webkit-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center}.align-self-middle{-ms-flex-item-align:center;-webkit-align-self:center;align-self:center}.align-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;-webkit-align-items:stretch;align-items:stretch}.align-self-stretch{-ms-flex-item-align:stretch;-webkit-align-self:stretch;align-self:stretch}.align-center-middle{-webkit-box-pack:center;-ms-flex-pack:center;-webkit-box-align:center;-ms-flex-align:center;-ms-flex-line-pack:center;-webkit-align-content:center;align-content:center;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.small-order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;-webkit-order:1;order:1}.small-order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;-webkit-order:2;order:2}.small-order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;-webkit-order:3;order:3}.small-order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;-webkit-order:4;order:4}.small-order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;-webkit-order:5;order:5}.small-order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;-webkit-order:6;order:6}@media print,screen and (min-width:40em){.medium-order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;-webkit-order:1;order:1}.medium-order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;-webkit-order:2;order:2}.medium-order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;-webkit-order:3;order:3}.medium-order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;-webkit-order:4;order:4}.medium-order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;-webkit-order:5;order:5}.medium-order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;-webkit-order:6;order:6}}@media print,screen and (min-width:64em){.large-order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;-webkit-order:1;order:1}.large-order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;-webkit-order:2;order:2}.large-order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;-webkit-order:3;order:3}.large-order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;-webkit-order:4;order:4}.large-order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;-webkit-order:5;order:5}.large-order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;-webkit-order:6;order:6}}.flex-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flex-child-auto{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.flex-child-grow{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto}.flex-child-shrink{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.flex-dir-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.flex-dir-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flex-dir-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.flex-dir-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}@media print,screen and (min-width:40em){.medium-flex-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.medium-flex-child-auto{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.medium-flex-child-grow{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto}.medium-flex-child-shrink{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.medium-flex-dir-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.medium-flex-dir-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.medium-flex-dir-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.medium-flex-dir-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}}@media print,screen and (min-width:64em){.large-flex-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.large-flex-child-auto{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.large-flex-child-grow{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto}.large-flex-child-shrink{-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.large-flex-dir-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}.large-flex-dir-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.large-flex-dir-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.large-flex-dir-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}}.hide{display:none!important}.invisible{visibility:hidden}.visible{visibility:visible}@media print,screen and (max-width:39.99875em){.hide-for-small-only{display:none!important}}@media screen and (max-width:0em),screen and (min-width:40em){.show-for-small-only{display:none!important}}@media print,screen and (min-width:40em){.hide-for-medium{display:none!important}}@media screen and (max-width:39.99875em){.show-for-medium{display:none!important}}@media print,screen and (min-width:40em)and (max-width:63.99875em){.hide-for-medium-only{display:none!important}}@media screen and (max-width:39.99875em),screen and (min-width:64em){.show-for-medium-only{display:none!important}}@media print,screen and (min-width:64em){.hide-for-large{display:none!important}}@media screen and (max-width:63.99875em){.show-for-large{display:none!important}}@media print,screen and (min-width:64em)and (max-width:74.99875em){.hide-for-large-only{display:none!important}}@media screen and (max-width:63.99875em),screen and (min-width:75em){.show-for-large-only{display:none!important}}.show-for-sr,.show-on-focus{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}.show-on-focus:active,.show-on-focus:focus{clip:auto!important;height:auto!important;overflow:visible!important;position:static!important;white-space:normal!important;width:auto!important}.hide-for-portrait,.show-for-landscape{display:block!important}@media screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:block!important}}@media screen and (orientation:portrait){.hide-for-portrait,.show-for-landscape{display:none!important}}.hide-for-landscape,.show-for-portrait{display:none!important}@media screen and (orientation:landscape){.hide-for-landscape,.show-for-portrait{display:none!important}}@media screen and (orientation:portrait){.hide-for-landscape,.show-for-portrait{display:block!important}}.show-for-dark-mode{display:none}.hide-for-dark-mode{display:block}@media screen and (prefers-color-scheme:dark){.show-for-dark-mode{display:block!important}.hide-for-dark-mode{display:none!important}}.show-for-ie{display:none}@media (-ms-high-contrast:active),(-ms-high-contrast:none){.show-for-ie{display:block!important}.hide-for-ie{display:none!important}}.show-for-sticky{display:none}.is-stuck .show-for-sticky{display:block}.is-stuck .hide-for-sticky{display:none}@font-face{font-display:"swap";font-family:FontAwesome}html{box-sizing:border-box;scroll-padding-top:100px}body{font-family:Roboto,sans-serif;font-size:16px;line-height:1}*,:after,:before{box-sizing:inherit}a{color:#3c4fe0}a.reference:after{font-family:FontAwesome;font-size:12px;padding:0 4px}a.reference.external:after{content:""}a.reference.download:after{content:""}a:hover{color:#3c4fe0;font-weight:500}.headerlink{margin-left:5px;visibility:hidden}.toc-backref:hover{color:#23263b}h1,h2,h3,h4,h5,h6{font-family:Roboto,sans-serif;font-size:16px;font-weight:500;letter-spacing:.2px;line-height:24px;margin-bottom:16px}h1:hover>a.headerlink,h2:hover>a.headerlink,h3:hover>a.headerlink,h4:hover>a.headerlink,h5:hover>a.headerlink,h6:hover>a.headerlink{visibility:visible}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color:inherit}h1{font-size:32px;font-weight:700;line-height:40px;margin-bottom:28px}h2{font-size:24px;line-height:32px}h3{font-size:20px}h4{font-size:18px}h5{font-size:16px}h6{font-weight:400}img{max-width:100%}button:focus{outline:0}blockquote{border:0;margin:0;padding:0}blockquote,blockquote p,cite{color:inherit}cite{display:inline;font-size:inherit}cite:before{content:""}.show{display:block!important}.centered{display:block;margin:0 auto}.break{flex-basis:100%;height:0}@media screen and (min-width:1024px){h1{font-size:36px}}.admonition-title:before,.contents.local>ul>li a:before,.scylla-icon,.secondary-side-nav__content li a:before{background-repeat:no-repeat;background-size:contain;display:inline-block;filter:brightness(0);vertical-align:middle}.scylla-icon--about-team{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1taXRlcmxpbWl0OjEwfS5jbHMtMntzdHJva2UtbGluZWNhcDpyb3VuZH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik00LjY2IDkuODEgMi42MyAxMWEyLjA4IDIuMDggMCAwIDAtMS4xMyAxLjgzdjcuODFjLjE5IDEuMTEuNSAxLjUzIDEuNSAxLjQ3TTcuMDYgOS45NGwxLjQ0Ljk0IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMy41IDE4LjV2NS4zNE05LjUgMTguNXY1LjM0TTguNTQgMTguNDJ2NS4zM00xNS41IDE4LjV2NS4zNE0xNi41IDE4LjV2NS4zNE0zLjMzIDIwLjUzaDUuMDhNMTEuNDUgOC44NGwuMDYuMDZhMS42NSAxLjY1IDAgMCAwIDIuMzQgMGgwIiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMTIuNDIgNy41YTEuODEgMS44MSAwIDAgMS0xLjkyLTEuNzdWNWExLjk0IDEuOTQgMCAwIDEgMS45Mi0yIDIuMDcgMi4wNyAwIDAgMSAyLjA4IDJ2Ljc3YTIgMiAwIDAgMS0yLjA4IDEuNzNaTTExLjQyIDguNzQgOS42MyA5LjlhMi4wNyAyLjA3IDAgMCAwLTEuMTMgMS44NXY3LjgyQTEuNDcgMS40NyAwIDAgMCAxMCAyMU0xMy43NSA5LjE4bDIgLjY1Yy43LjM1Ljc2IDEuMDYuNzYgMS44NHY3LjljMCAuNzctLjIzIDEuMjQtMSAxLjI0IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNOS45MyAxOS41aDUuNCIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTE5LjQyIDkuMTJhMi4wNyAyLjA3IDAgMCAwIDIuMDgtMS45M3YtLjc3YTIuMDcgMi4wNyAwIDAgMC0yLjA4LTEuOTIgMS45MyAxLjkzIDAgMCAwLTEuOTIgMS45MnYuNzdhMS45NCAxLjk0IDAgMCAwIDEuOTIgMS45M1pNNS41OSA5LjEyYTEuOTMgMS45MyAwIDAgMCAxLjkyLTEuOTN2LS43N0ExLjkzIDEuOTMgMCAwIDAgNS41OSA0LjUgMi4wOCAyLjA4IDAgMCAwIDMuNSA2LjQydi43N2EyLjA4IDIuMDggMCAwIDAgMi4wOSAxLjkzWk0yMC40NCA5LjgxbDIgMS4xN2EyLjA2IDIuMDYgMCAwIDEgMS4xMyAxLjg1djcuODFjLS4xOCAxLjExLS40NyAxLjUzLTEuNDcgMS40N00xOC4wNCA5Ljk0bC0xLjQ0LjkzIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMjEuNiAxOC41djUuMzRNMjEuNzcgMjAuNTNoLTUuMDgiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.scylla-icon--about-us{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8zIiB2aWV3Qm94PSIwIDAgMjAgMjAiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6LjhweH08L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNi4yOCAxOS40OGMtLjEyLjA4LS4wOC4wNy0uMjMuMS0uNTguMDktMS4xMi0uMjgtMS4yNS0uODQgMCAwLTIuMy05LjE4LTIuMy0xMS4xMUMyLjUgMy42IDUuODguNDQgMTAuMzguNDRTMTcuNSAzLjQ4IDE3LjUgNy41YzAgMS45My0xLjMyIDExLjIzLTEuMzIgMTEuMjMtLjEzLjU2LS42Ny45NC0xLjI1Ljg0LS4xMi0uMDItLjEzIDAtLjIzLS4wNyIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTE1Ljc1IDE1Ljc1Yy0uMTcgMS4xNS0uMjIgMi4zNC0uNTUgMy40Ni0uMzcuODUtMS42MyAxLjA2LTIuMjIuMzMtLjI1LS4yOC4xOS0uNjguNDQtLjQuNDMuNDYgMS4yNC4xOCAxLjMxLS40NGwuMDYtLjM0Yy4xOS0uODkuMzUtMS43OS41Ny0yLjY4LjA1LS4yNC40Mi0uMTcuMzkuMDdaIi8+PHBhdGggZD0iTTExLjUgN2MwIDEuOS0xLjU2IDMuNS0zLjQ2IDMuNVM0LjUgOC45IDQuNSA3czEuNjQtMy41IDMuNTQtMy41UzExLjUgNS4xIDExLjUgN1oiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik04LjU1IDQuNzVjLS41OS4xMi0uNzEgMS40Mi0uMzYgMS43OC4yMy4yMy43MS4zMS43MS40N3MtLjQ4LjI0LS43MS40N2MtLjM2LjM2LS4yNCAxLjY2LjM2IDEuNzguNzEuMTQgMS43OC0uNzEgMS43OC0yLjI1UzkuMjYgNC42MSA4LjU1IDQuNzVaTTYuNTEgMTIuMmMyLjEyLjMxIDQuMzQtLjIgNS42OC0xLjk2LjMyLS40MS45Ni4xMS42Mi41MS0uNzYuOS0xLjc4IDEuNjMtMi45MyAxLjk1LTEuMTQuMzMtMi4zMy4zMS0zLjQ2LjE2YS4zNC4zNCAwIDAgMS0uMjktLjM4Yy4wMi0uMTguMTktLjMxLjM3LS4yOVpNNy45NyAxOS41OWMtLjk5Ljk2LTIuMzYuMDgtMi4zNi0xLjE1LS4xMi0uOS0uMjctMS43OS0uMzctMi42OS0uMDEtLjExLjA3LS4yMS4xOC0uMjIuMS0uMDEuMTkuMDYuMjEuMTUuMjIuODguMzggMS43Ny41NiAyLjY2LjAxLjc4LjY4IDEuMzggMS4zNS44My4yNy0uMjcuNjkuMTYuNDIuNDNaIi8+PHBhdGggZD0iTTkuNzUgMTkuMjdjLS40Mi45LTEuOC45Ni0yLjMyLjExLS41LTEuMTMtLjMxLTIuNS0uNDctMy43MiAwLS4xMS4wOC0uMi4xOS0uMjEuMSAwIC4xOS4wNy4yMS4xNy4xNy45NS4yOCAxLjkxLjQyIDIuODcuMDEuNDUuMjMuNzQuNTcuODUuMzMuMS43MS0uMDUuODgtLjM2LjE4LS4zNC43MS0uMDUuNTIuMjlaTTE0LjAzIDE1LjY2Yy0uMTYgMS4yMy4wMyAyLjU3LS40NiAzLjcyLS41Mi44Ni0xLjkxLjc5LTIuMzItLjExLS4xNy0uMzQuMzUtLjYxLjUzLS4yOC40Mi43MSAxLjQ4LjM4IDEuNDUtLjQ5LjE0LS45Ni4yNS0xLjkyLjQyLTIuODcuMDQtLjI0LjQxLS4yLjQuMDRaIi8+PHBhdGggZD0iTTExLjg1IDE1LjU0Yy4wMi43OS4wMSAxLjU4LjAxIDIuMzctLjAyLjQxLjA3LjktLjE0IDEuMjktLjQzIDEuMDItMi4wMSAxLjAyLTIuNDUgMC0uMjEtLjM5LS4xMy0uODktLjE0LTEuMjkgMC0uNzkgMC0xLjU4LjAxLTIuMzcgMC0uMTEuMS0uMi4yMS0uMTkuMSAwIC4xOC4wOC4xOS4xOC4wNy43OS4xIDEuNTguMTUgMi4zNy4wMy4yNyAwIC44Mi4xMyAxLjA0LjEzLjI2LjQuNDMuNjguNDIuNDYgMCAuNzktLjQuNzctLjg3bC4wMy0uNTljLjA0LS43OS4wOC0xLjU4LjE1LTIuMzcuMDItLjI0LjQtLjIzLjQuMDFaIi8+PC9zdmc+)}.scylla-icon--about-us-m{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNi4zOCAzMi40MyI+PHBhdGggZD0iTTYuNTUgMzEuNjRjLS4yLjEzLS40My4yMi0uNjkuMjZhMS44MSAxLjgxIDAgMCAxLTIuMDYtMS4zOVMuNDkgMTQuOTkuNDkgMTEuODJDLjUgNS4xOSA1Ljc3LjUgMTMuMTkuNXMxMi42OSA0LjY5IDEyLjY5IDExLjMyYzAgMy4xOC0zLjMxIDE4LjY5LTMuMzEgMTguNjlhMS44MSAxLjgxIDAgMCAxLTIuNjIgMS4yIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZCIvPjxwYXRoIGQ9Ik0yMS44NiAyNS4zNmMtLjI4IDEuOS0uMzcgMy44Ni0uOTEgNS43MS0uNjEgMS40MS0yLjY4IDEuNzUtMy42Ni41NS0uNDEtLjQ3LjMxLTEuMTEuNzMtLjY2LjcxLjc2IDIuMDQuMjkgMi4xNi0uNzMuMzItMS42Ni42NS0zLjMzIDEuMDQtNC45OC4wOS0uMzkuNy0uMjguNjUuMTFaIi8+PHBhdGggZD0iTTE0LjggMTAuNTdjMCAzLjEzLTIuNTMgNS42Ni01LjY2IDUuNjZzLTUuNDctMi41My01LjQ3LTUuNjYgMi4zNC01LjY2IDUuNDctNS42NiA1LjY2IDIuNTMgNS42NiA1LjY2WiIgc3R5bGU9InN0cm9rZS13aWR0aDouOXB4O2ZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQiLz48cGF0aCBkPSJNMTAuMzEgNi44NmMtLjk4LjItMS4xNyAyLjM0LS41OSAyLjkzLjM4LjM4IDEuMTcuNTEgMS4xNy43OHMtLjc5LjQtMS4xNy43OGMtLjU5LjU5LS4zOSAyLjczLjU5IDIuOTMgMS4xNi4yMyAyLjkzLTEuMTcgMi45My0zLjcxcy0xLjc2LTMuOTQtMi45My0zLjcxWk02LjgyIDE4LjUxYzMuNDkuODkgNi45Ny0uNSA5LjUxLTIuOTMuNDctLjQ0IDEuMTYuMzEuNjguNzQtMS4zOCAxLjIzLTIuOTggMi4yOS00Ljc5IDIuODctMS44LjU5LTMuNzcuNTgtNS41OC4xNGEuNDIxLjQyMSAwIDAgMS0uMzEtLjVjLjA1LS4yMi4yOC0uMzYuNS0uMzFaIi8+PHBhdGggZD0iTTE2LjczIDE2LjY3Yy0uMTItLjQ2LS41MS0uODMtLjk5LS44My0uNzUtLjAyLS41OS0xLjE3LjE0LS45OS44MS4xNiAxLjQzLjg1IDEuNSAxLjY2LjA4LjQtLjU0LjU0LS42NS4xNVpNOS4wMyAzMS43Yy0xLjI2IDEuMzYtMy42Mi40NS0zLjgtMS4zNWwtLjA5LS41NWMtLjIxLTEuNDgtLjQ1LTIuOTUtLjYtNC40NC0uMDItLjE4LjExLS4zNC4yOS0uMzYuMTctLjAyLjMyLjA5LjM1LjI1LjM5IDEuNjMuNzEgMy4yOCAxLjAzIDQuOTMuMDkgMS4wMiAxLjM4IDEuNTQgMi4xMi44MS40NS0uNDQgMS4xNC4yNi42OS43WiIvPjxwYXRoIGQ9Ik0xMS45NiAzMS4xNmMtMSAxLjk4LTQuMDQgMS4zLTQuMjEtLjg4LS4xNS0xLjY5LS4zLTMuMzgtLjM5LTUuMDcgMC0uMTguMTMtLjM0LjMxLS4zNC4xNyAwIC4zMS4xMS4zNC4yNy4yOCAxLjY3LjUgMy4zNS43MiA1LjAzLjA5IDEuMiAxLjc3IDEuNTkgMi4zNi41MS4zMS0uNTYgMS4xNi0uMDkuODcuNDdaTTE5LjAzIDI1LjIxYy0uMDggMS42OS0uMjQgMy4zOC0uMzkgNS4wNy0uMDQuMzctLjE3Ljc1LS4zOCAxLjA2LS44NiAxLjQtMy4xMSAxLjMxLTMuODMtLjE3LS4zLS41Ni41NS0xLjAzLjg2LS40OC41OSAxLjA4IDIuMjcuNjkgMi4zNS0uNTIuMjItMS42OC40My0zLjM2LjcyLTUuMDMuMDYtLjQuNjgtLjMzLjY1LjA3WiIvPjxwYXRoIGQ9Ik0xNS40MyAyNS4wMmMuMDQgMS4zMS4wMiAyLjYxLjAyIDMuOTEtLjAzLjY3LjExIDEuNDgtLjIzIDIuMTMtLjc0IDEuNjktMy4yOSAxLjY5LTQuMDMgMC0uMzQtLjY1LS4yMS0xLjQ3LS4yNC0yLjEzIDAtMS4zLS4wMi0yLjYxLjAyLTMuOTEgMC0uMTguMTYtLjMyLjM0LS4zMi4xNyAwIC4zLjE0LjMyLjMuMTEgMS4zLjE3IDIuNi4yNCAzLjkxLjA1LjQ1IDAgMS4zNS4yMSAxLjcyLjIxLjQzLjY2LjcxIDEuMTIuNy40Ni4wMi45MS0uMjcgMS4xMi0uNjkuMjItLjM2LjE2LTEuMjguMjEtMS43Mi4wNy0xLjMuMTMtMi42MS4yNC0zLjkxLjAyLS40LjY2LS4zOC42Ni4wMloiLz48L3N2Zz4=)}.scylla-icon--alternator{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8zIiB2aWV3Qm94PSIwIDAgMjAgMjAiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH08L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNMTcuNSAyLjkxYzAgMS4yOC0zLjY3IDIuNTktOCAyLjU5cy04LTEuMzEtOC0yLjU5UzUuMDkuNSA5LjQyLjVzOC4wOCAxLjEzIDguMDggMi40MVpNMTcuNSA3LjY2YzAgMS4yOC0zLjYzIDIuOC03Ljk2IDIuOFMxLjUgOC45MyAxLjUgNy42Nk0xNy41IDEyLjQ3YzAgMS4yOC0zLjY3IDMuMDMtOCAzLjAzcy04LTEuNzUtOC0zLjAzTTE3LjUgMTcuMjljMCAxLjI4LTMuNzUgMi4zLTguMDggMi4zcy03LjkyLTEuMDMtNy45Mi0yLjNNMS41IDE3LjE5VjIuOTFNMTcuNSAxNy4xOVYyLjkxIiBjbGFzcz0iY2xzLTEiLz48L3N2Zz4=)}.scylla-icon--apps{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTS41IDEuNWgyMHYxNEguNXpNNy41IDE1Ljc0djIuODlNMTIuODMgMTUuNjN2Mi4zMk01LjUgMTguNWg5LjE0IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtMy42NCA1LjU2IDQuNTggMi45MS00LjU4IDIuOTJNOS4xIDEyLjA4aDQuMzIiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--architecture{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTIsLmNscy01e2ZpbGw6bm9uZTtzdHJva2U6Z3JheX0uY2xzLTF7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfS5jbHMtMiwuY2xzLTV7c3Ryb2tlLW1pdGVybGltaXQ6MTB9LmNscy0ye3N0cm9rZS13aWR0aDouOThweH0uY2xzLTV7c3Ryb2tlLXdpZHRoOi45OXB4fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfMiIgZGF0YS1uYW1lPSJDYWxxdWUgMiI+PHBhdGggZD0iTTEuOSAxMC4yN2ExMC44MyAxMC44MyAwIDAgMSA4LjczLTguMzhNMTAuNTEgMjMuMDhBMTAuNzkgMTAuNzkgMCAwIDEgMS43NyAxNE0yMy4yMyAxNGExMC44MSAxMC44MSAwIDAgMS05IDkuMTFNMTQuMjcgMS44OGExMC44MSAxMC44MSAwIDAgMSA4LjgzIDguMzciIGNsYXNzPSJjbHMtMSIvPjxjaXJjbGUgY3g9IjEyLjI1IiBjeT0iMS43NSIgcj0iMS43NSIgY2xhc3M9ImNscy0yIi8+PGNpcmNsZSBjeD0iMTIuMjUiIGN5PSIyMi43NSIgcj0iMS43NSIgY2xhc3M9ImNscy0yIi8+PGNpcmNsZSBjeD0iNC45MiIgY3k9IjQuNzUiIHI9IjEuNzUiIHN0eWxlPSJzdHJva2Utd2lkdGg6Ljk5cHg7ZmlsbDpncmF5O3N0cm9rZS1taXRlcmxpbWl0OjEwO3N0cm9rZTpncmF5Ii8+PGNpcmNsZSBjeD0iMjAuMDkiIGN5PSIxOS45MSIgcj0iMS43NSIgc3R5bGU9InN0cm9rZS13aWR0aDouOTlweDtmaWxsOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlOmdyYXkiLz48Y2lyY2xlIGN4PSIxLjc1IiBjeT0iMTIuMjUiIHI9IjEuNzUiIGNsYXNzPSJjbHMtNSIvPjxjaXJjbGUgY3g9IjIzLjI1IiBjeT0iMTIuMjUiIHI9IjEuNzUiIGNsYXNzPSJjbHMtNSIvPjxjaXJjbGUgY3g9IjQuNzUiIGN5PSIxOS42NCIgcj0iMS43NSIgc3R5bGU9InN0cm9rZS13aWR0aDouOTlweDtmaWxsOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlOmdyYXkiLz48Y2lyY2xlIGN4PSIxOS45MSIgY3k9IjQuNDgiIHI9IjEuNzUiIHN0eWxlPSJzdHJva2Utd2lkdGg6Ljk5cHg7ZmlsbDpncmF5O3N0cm9rZS1taXRlcmxpbWl0OjEwO3N0cm9rZTpncmF5Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--benchmarks{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDozcHh9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV8yIiBkYXRhLW5hbWU9IkNhbHF1ZSAyIj48cGF0aCBkPSJNNS41MSAyNC45MXYtNS44NU0xMi41NyAyNC45MXYtOS43NE0xOS42MiAyNC45MVYxMC4xNSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibS45MSAxNC45OCA1LjEzLTcuOTQgNi4yNSA1Ljg4TDI0IDEiIHN0eWxlPSJzdHJva2UtbGluZWNhcDpyb3VuZDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVqb2luOnJvdW5kIi8+PHBhdGggZD0ibTI1IDUtNS01aDV2NXoiIHN0eWxlPSJmaWxsOmdyYXkiLz48L2c+PC9zdmc+)}.scylla-icon--blog{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibTkgMTUtMi41LTEuNSA4LTEyTDE3IDMgOSAxNXoiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Im02LjUgMTMuNS0uNSAzTDkgMTVsLTIuNS0xLjV6IiBzdHlsZT0iZmlsbDpncmF5O3N0cm9rZTpncmF5O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZCIvPjxwYXRoIGQ9Ik0xOS4yNSAyLjVoNC4yNXYxNmgtMTN2NC4xN0w2LjQ2IDE4LjVsLTQuOTYtLjA0VjIuNWg4LjMxTTE0LjUgMi41bDEuNjcgMS4zMyIgY2xhc3M9ImNscy0xIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--careers{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTEuNSAxMS41NXY4YzAgLjU2IDEuMDcgMiAyIDJoMThjLjg5IDAgMi0xLjQ0IDItMnYtOCIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTIzLjMxIDMuNUgxLjgxYy0uNDggMC0xLjMxLjU1LTEuMzEgMXY2bDEwIDJhOC40NSA4LjQ1IDAgMCAwIDQgMGwxMC0ydi02YzAtLjQ1LS43Mi0xLTEuMTktMVpNMTUuNjIgMy41di0xYzAtLjc2LS42MS0xLTEuMzgtMWgtMy40NWMtLjc2IDAtMS4zOC4yNC0xLjM4IDF2MSIgY2xhc3M9ImNscy0xIi8+PHJlY3Qgd2lkdGg9IjUiIGhlaWdodD0iMy45OSIgeD0iMTAiIHk9IjExIiByeD0iLjU1IiByeT0iLjU1IiBzdHlsZT0iZmlsbDpncmF5Ii8+PC9zdmc+)}.scylla-icon--chevron-left{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTguMDkyIDE2IDEwIDE0LjExMyAzLjgxNyA4IDEwIDEuODg3IDguMDkyIDAgMCA4bDguMDkyIDhaIi8+PC9zdmc+)}.contents.local>ul>li a:before,.scylla-icon--chevron-right,.secondary-side-nav__content li a:before{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTEuOTA4IDAgMCAxLjg4NyA2LjE4MyA4IDAgMTQuMTEzIDEuOTA4IDE2IDEwIDggMS45MDggMFoiLz48L3N2Zz4=)}.scylla-icon--circe{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOCAzMCI+PGRlZnM+PHN0eWxlPi5jbHMtMiwuY2xzLTN7ZmlsbDpub25lO3N0cm9rZTojNGQ0ZDRkO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH0uY2xzLTN7c3Ryb2tlLXdpZHRoOjEuMTFweH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik0yMi4xIDEyaC02LjE2YTEuMDYgMS4wNiAwIDAgMS0uOTQtMS4wNy45My45MyAwIDAgMSAuOTQtLjkzaDYuMTZhLjkzLjkzIDAgMCAxIC45NC45M0ExLjA2IDEuMDYgMCAwIDEgMjIuMSAxMloiIHN0eWxlPSJmaWxsOiM0ZDRkNGQiLz48cGF0aCBkPSJNMTMuNDQgNC40OUg5LjUxdjI0aDE5di0yNEgyNC41IiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMTMgMy40OUg4LjVsLS4wOCAyNi4xSDI5LjVWMy4zOUgyNSIgY2xhc3M9ImNscy0zIi8+PHBhdGggZD0iTTEyLjUgMTguMzhoMTNNMTIuNSAxNS40OWgxM00xMi41IDIxLjQzaDEzTTEyLjUgMjQuNDdoMTNNMTMuNSAyLjVoMTF2My45OGgtMTF6IiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMjEuNS41aC01LjA0djEuOTVsNS4wNC4wNXYtMnoiIGNsYXNzPSJjbHMtMyIvPjwvZz48L3N2Zz4=)}.scylla-icon--clock{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PGNpcmNsZSBjeD0iMTAuNSIgY3k9IjkuNSIgcj0iOSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTEwLjUgMy41djZsMy4wNiAzIiBjbGFzcz0iY2xzLTEiLz48L2c+PC9zdmc+)}.scylla-icon--close{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNCIgaGVpZ2h0PSIzNCIgZmlsbD0ibm9uZSI+PGcgZmlsbD0iI2ZmZiIgY2xpcC1wYXRoPSJ1cmwoI2EpIj48cGF0aCBkPSJNMTEuNjcgMjIuMTNhLjU2NC41NjQgMCAwIDEtLjM5OC0uOTYybDkuODk2LTkuODk2YS41NjMuNTYzIDAgMSAxIC43OTcuNzk3bC05Ljg5NiA5Ljg5NmEuNTU5LjU1OSAwIDAgMS0uMzk5LjE2NVoiLz48cGF0aCBkPSJNMjEuNTY2IDIyLjEzYS41NTkuNTU5IDAgMCAxLS4zOTgtLjE2NWwtOS44OTYtOS44OTZhLjU2My41NjMgMCAxIDEgLjc5Ny0uNzk3bDkuODk2IDkuODk1YS41NjQuNTY0IDAgMCAxLS4zOTkuOTYzWiIvPjxwYXRoIGQ9Ik0xNi42MTkgMzMuMjM3QzcuNDU1IDMzLjIzNyAwIDI1Ljc4MiAwIDE2LjYxOSAwIDcuNDU2IDcuNDU1IDAgMTYuNjE5IDBzMTYuNjE5IDcuNDU1IDE2LjYxOSAxNi42MTktNy40NTYgMTYuNjE4LTE2LjYyIDE2LjYxOFptMC0zMi4xMWMtOC41NDIgMC0xNS40OTIgNi45NS0xNS40OTIgMTUuNDkyIDAgOC41NDIgNi45NSAxNS40OTIgMTUuNDkyIDE1LjQ5MiA4LjU0MiAwIDE1LjQ5Mi02Ljk1IDE1LjQ5Mi0xNS40OTIgMC04LjU0Mi02Ljk1LTE1LjQ5Mi0xNS40OTItMTUuNDkyWiIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMzMuMjM3djMzLjIzN0gweiIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg==)}.scylla-icon--cloud{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8yIiB2aWV3Qm94PSIwIDAgNDMuMDQgMzIuMDMiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDpub25lO3N0cm9rZTojMWQxZDFiO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iTGF5ZXJfMyI+PHBhdGggZD0iTTQyLjU0IDQuMDZjMCAxLjY4LTMuNjMgMi40NC05IDIuNDRzLTEwLS43My0xMC0yLjRTMjcuNjcuNSAzMy4wNC41czkuNSAxLjg5IDkuNSAzLjU2Wk00Mi41NCA5LjYzYzAgMS42OC0zLjc2IDIuOTEtOS4xMiAyLjkxcy05Ljg0LTEuMjMtOS44NC0yLjkxTTQyLjU0IDE1LjM0YzAgMS42OC0zLjY4IDMuMjUtOS4wNCAzLjI1LTQgMC03LjYtLjk2LTkuMDktMi4wNE00Mi41NCAyMC42NWMwIDEuNjgtMy43MiAyLjk3LTkuMDggMi45N00yMy41NCAxNS40NlY0LjFNNDIuNTQgMjAuNzdWNC4xIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMjguMTEgMjEuMDhjLS44NyAwLTEuNjcuMjMtMi4zOS42MSAwLS4wNy4wMS0uMTQuMDEtLjIxIDAtNC44NS0zLjgzLTguOS04LjY4LTguOXMtOC44OCA0LjA1LTguODggOC45YzAgLjE3LjAyLjM0LjAzLjUxLS44NC0uNTctMS44NS0uOTEtMi45NS0uOTEtMi44OCAwLTQuNzQgMi41Ny00Ljc0IDUuNDZzMS44NiA0Ljk5IDQuNzQgNC45OWgyMi44NmMyLjg4IDAgNS41Mi0yLjI3IDUuNTItNS4xNnMtMi42My01LjI5LTUuNTItNS4yOVoiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--cloud-docs{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTYuNSAxMS41aDh2MWgtOHpNMTUuNjUgNi41NWEzLjQyIDMuNDIgMCAwIDAtMy4xNSAyIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMTAuMDYgMi44QTUuMTcgNS4xNyAwIDAgMSAxNSA2LjM1aC4yNGE0Ljg0IDQuODQgMCAwIDEgMCA5LjY3aC0xMWEzLjQ1IDMuNDUgMCAwIDEgMC02LjlBMy4xNyAzLjE3IDAgMCAxIDUgOS4yIDUuMzMgNS4zMyAwIDAgMSA0Ljg2IDhhNS4yIDUuMiAwIDAgMSA1LjItNS4ybTAtLjhhNiA2IDAgMCAwLTYgNnYuMzFhNC4yNSA0LjI1IDAgMCAwIC4xOCA4LjQ5aDExYTUuNjMgNS42MyAwIDAgMCAuMy0xMS4yNkE2IDYgMCAwIDAgMTAuMDYgMloiIHN0eWxlPSJmaWxsOiM0ZDRkNGQiLz48L2c+PC9zdmc+)}.scylla-icon--comparison{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTIsLmNscy00e2ZpbGw6bm9uZTtzdHJva2U6Z3JheX0uY2xzLTEsLmNscy0ye3N0cm9rZS1taXRlcmxpbWl0OjEwfS5jbHMtMiwuY2xzLTR7c3Ryb2tlLWxpbmVjYXA6cm91bmR9LmNscy00e3N0cm9rZS1saW5lam9pbjpyb3VuZH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik00LjUgMTMuNjN2Mi44OGg2LjA2TTIwLjUgMTMuNTR2Mi45NmwtNS41LjAxIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMTIuNSAxOC41djIuNzJNNy41IDIxLjVoMTAiIGNsYXNzPSJjbHMtMiIvPjxjaXJjbGUgY3g9IjEyLjUiIGN5PSIxNi41IiByPSIyIiBzdHlsZT0iZmlsbDpncmF5O3N0cm9rZS13aWR0aDouOTVweDtzdHJva2UtbWl0ZXJsaW1pdDoxMDtzdHJva2U6Z3JheSIvPjxwYXRoIGQ9Ik01LjA2IDEzLjU4SDMuODhBMy4xIDMuMSAwIDAgMSAuNSAxMC41aDhhMy4xNiAzLjE2IDAgMCAxLTMuNDQgMy4wOFpNMjEgMTMuNThoLTEuMTdhMy4wOSAzLjA5IDAgMCAxLTMuMzctMy4wN2g4QTMuMTYgMy4xNiAwIDAgMSAyMSAxMy41OFpNNy40NiA1LjEyYzAgLjU3LTEuMS40Ni0yLjc5LjQ2UzEuNTggNS42IDEuNTggNSAzIDQuNCA0LjY5IDQuNHMyLjc3LjE2IDIuNzcuNzJaTTEuNSA5Ljg1VjUuMzFNNy41IDEwLjM1VjUuODFNMjMuNSA1LjEyYzAgLjU3LTEuMS40Ni0yLjc5LjQ2cy0zLjA5IDAtMy4wOS0uNTRTMTkgNC40IDIwLjczIDQuNHMyLjc3LjE2IDIuNzcuNzJaTTE3LjU0IDkuODVWNS4zMU0yMy41NCAxMC4zNVY1LjgxIiBjbGFzcz0iY2xzLTQiLz48L2c+PC9zdmc+)}.scylla-icon--contact-us{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjEuMDZweH08L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJtNi4yOTggMTAuMTggMTMuODMtNy4xOTcgNC42NzYgOC45ODYtMTMuODMgNy4xOTd6IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtNi4zIDEwLjE4IDguNjMgMS41NmExLjQyIDEuNDIgMCAwIDAgMS41My0uNzRsMy42Ny04TTExLjAyIDE5LjAzbDEuNzQtNU0yNC41OSAxMS45N2wtNS4wOS0xLjQ1TTcuMDkgMTcuNTggMy45IDE5LjM0TTYuMDYgMTUuNDEuNTQgMTguMzYiIGNsYXNzPSJjbHMtMSIvPjwvc3ZnPg==)}.scylla-icon--developers-blog{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOmdyYXl9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJtNi40OCAxMC41OS0uNS4xNy41LjE2TDExIDEyLjE2VjE0bC03LTIuNDlWMTBsNy0yLjV2MS44M1pNMTQgOS4zMlY3LjVsNyAyLjV2MS41NEwxNCAxNHYtMS44M2w0LjE0LTEuMy40NC0uMTMtLjQzLS4xNFoiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik0xLjUgMi41aDIydjE2aC0xM3Y0LjE3TDYuNDYgMTguNWwtNC45Ni0uMDRWMi41eiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOi45OHB4Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--docs{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfS5jbHMtMntmaWxsOmdyYXl9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJNMy41IDIuNTFoMTYuOTR2MjAuOTFIMy41eiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTIyLjQ1IDIxLjUuMDUtMjFoLTE3YTIuMTYgMi4xNiAwIDAgMC0yIDIiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik02IDZoN3YySDZ6TTYgOWgxMXYySDZ6IiBjbGFzcz0iY2xzLTIiLz48L2c+PC9zdmc+)}.scylla-icon--enterprise{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8zIiB2aWV3Qm94PSIwIDAgMjAgMjAiPjxkZWZzPjxzdHlsZT4uY2xzLTEsLmNscy0ye2ZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9LmNscy0ye3N0cm9rZS13aWR0aDoxLjA3cHh9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0ibTEzLjYyIDcuNSAxLjg4LTEuMDggMiAyLjA4djdoMU0xNS41IDE1LjV2LTUiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik01LjUgMTUuNXYtMTJsNC0yIDQgMnYxMk05LjUgMTUuNVYxLjZNNy41IDUuNXYxME0xMS41IDUuNXYxMCIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTUuNSA4LjU0IDMuNDYgNy41bC0xLjk2Ljk2djcuMDRoLTFNMy41IDEwLjV2NU0uNSAxNy41aDE4IiBjbGFzcz0iY2xzLTEiLz48L3N2Zz4=)}.scylla-icon--enterprise-m{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIGlkPSJMYXllcl8yXzAwMDAwMDE2NzY4MDY2MDE5MjYzMjMyNzcwMDAwMDA1NDc1ODA5NTExODI4NjY2MDM2XyIgeD0iMCIgeT0iMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDMgMzEiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDQzIDMxIj48c3R5bGU+LnN0MHtmaWxsOm5vbmU7c3Ryb2tlOiMxZDFkMWI7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PGcgaWQ9IkxheWVyXzMiPjxwYXRoIGQ9Im0yOS42IDkuNSA0LTIgNi45IDQuMXYxNS45aDJNMzMuNiAyNy41VjcuNk0xNC42IDI3LjVWNC44TDIyLjUuNSAyOS42IDV2MjIuNU0yMi41IDI3LjVWMU0yNC41IDUuNmwzIDJNMjQuNSA5LjZsMyAyTTI0LjUgMTMuNmwzIDJNMjQuNSAxNy41bDMgMk0yNC41IDIxLjVsMyAyTTM1LjQgMTEuNmwzIDJNMzUuNCAxNS42bDMgMS45TTM1LjQgMTkuNWwzIDJNMzUuNCAyMy41bDMgMS45TTE4LjUgNS44djIxLjdNMTQuNiA5LjdsLTQuMS0yLjUtOCA0LjR2MTUuOWgtMk0xMC41IDI3LjVWNy4yTTEyLjUgMTEuNmwyIDFNMTIuNSAxNS42bDIgLjlNMTIuNSAxOS41bDIgMU0xMi41IDIzLjVsMi4xIDFNNi40IDEyLjR2MTUuMU0uNSAzMC41aDQyIiBjbGFzcz0ic3QwIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--events{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9LmNscy0ye2ZpbGw6Z3JheX08L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNMjIuNSAyMy41aC0yMXYtMjBoMjJ2MTUuMjEiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik00LjQyIDMuNWMwLTEuMzYgMS4wOS0yIDIuNDUtMmEyLjQ2IDIuNDYgMCAxIDEgMCA0LjkxIDIuNjEgMi42MSAwIDAgMS0xLS4yMU0xMC42NyAzLjVjMC0xLjM2IDEuMS0yIDIuNDYtMmEyLjQ2IDIuNDYgMCAwIDEgMCA0LjkxIDIuNjEgMi42MSAwIDAgMS0xLS4yMU0xNi45MyAzLjVjMC0xLjM2IDEuMS0yIDIuNDUtMmEyLjQ2IDIuNDYgMCAxIDEgMCA0LjkxIDIuNTIgMi41MiAwIDAgMS0xLS4yMSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTcgOWgzdjNIN3pNMTIgOWgzdjNoLTN6TTE3IDloM3YzaC0zek03IDE0aDN2M0g3ek0xMiAxNGgzdjNoLTN6TTE3IDE0aDN2M2gtM3oiIGNsYXNzPSJjbHMtMiIvPjxwYXRoIGQ9Ik0zLjUgMy42N3YxNi42Nk0zLjUgMjAuNDNjMCAxLjI5LjQ0IDIuMzMgMS43MyAyLjMzczIuMzMtMS45IDIuMzMtMy4xOWwxNi45NC0uMDdjMCAxLjI5LS41NSAzLjEyLTEuODMgMy4xMkg2LjMiIGNsYXNzPSJjbHMtMSIvPjwvc3ZnPg==)}.admonition.note .admonition-title:before,.admonition.tip .admonition-title:before,.scylla-icon--exclamation{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PG1hc2sgaWQ9ImEiIHdpZHRoPSIyMiIgaGVpZ2h0PSIyMiIgeD0iMSIgeT0iMSIgbWFzay10eXBlPSJhbHBoYSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTEyIDIzQzUuOSAyMyAxIDE4LjEgMSAxMlM1LjkgMSAxMiAxczExIDQuOSAxMSAxMS00LjkgMTEtMTEgMTFabTAtMjBjLTUgMC05IDQtOSA5czQgOSA5IDkgOS00IDktOS00LTktOS05WiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMiAxM2MtLjYgMC0xLS40LTEtMVY4YzAtLjYuNC0xIDEtMXMxIC40IDEgMXY0YzAgLjYtLjQgMS0xIDFaTTEyIDE3Yy0uMyAwLS41LS4xLS43LS4zLS4yLS4yLS4zLS40LS4zLS43IDAtLjEgMC0uMy4xLS40LjEtLjEuMS0uMi4yLS4zLjMtLjMuNy0uNCAxLjEtLjIuMSAwIC4xIDAgLjIuMSAwIDAgLjEuMS4yLjEuMS4xLjIuMi4yLjN2LjRjMCAuMSAwIC4zLS4xLjQtLjEuMS0uMS4yLS4yLjMtLjIuMi0uNC4zLS43LjNaIi8+PC9tYXNrPjxnIG1hc2s9InVybCgjYSkiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMjR2MjRIMHoiLz48L2c+PC9zdmc+)}.collapsible-button i,.scylla-icon--expand{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNi4wMDEiIGhlaWdodD0iMTYiPjxwYXRoIGQ9Ik01IDEzYTEgMSAwIDAgMS0uNzEtLjI5bC00LTRhMSAxIDAgMCAxIDAtMS40MWw0LTRhMSAxIDAgMCAxIDEuNDIgMS40MUwyLjQxIDhsMy4yOSAzLjI5QTEgMSAwIDAgMSA1IDEzeiIvPjxwYXRoIGQ9Ik0xMSA5SDFhMSAxIDAgMCAxIDAtMmgxMGExIDEgMCAwIDEgMCAyek0xNSAxNmExIDEgMCAwIDEtMS0xVjFhMSAxIDAgMCAxIDIgMHYxNGExIDEgMCAwIDEtMSAxeiIvPjwvc3ZnPg==)}.scylla-icon--forum{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItdXNlcnMiPjxwYXRoIGQ9Ik0xNyAyMXYtMmE0IDQgMCAwIDAtNC00SDVhNCA0IDAgMCAwLTQgNHYyIi8+PGNpcmNsZSBjeD0iOSIgY3k9IjciIHI9IjQiLz48cGF0aCBkPSJNMjMgMjF2LTJhNCA0IDAgMCAwLTMtMy44N00xNiAzLjEzYTQgNCAwIDAgMSAwIDcuNzUiLz48L3N2Zz4=)}.scylla-icon--home{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJMYXllcl81IiBkYXRhLW5hbWU9IkxheWVyIDUiPjxwYXRoIGQ9Ik0zLjUgNi4xNHYxMWExLjM4IDEuMzggMCAwIDAgMS4zNyAxLjM2aDExLjI2YTEuMzggMS4zOCAwIDAgMCAxLjM3LTEuMzd2LTExIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtMTkuNSA3LjUtOC02LjI1YTEuNTkgMS41OSAwIDAgMC0xLjk0IDBMMS41IDcuNU0xMi43MyAxOC4wMnYtNy4yMUg4LjI3djcuMjEiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--getting-started{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGcgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibTcgNC41IDguNTEgNS4wNUw3IDE0LjV2LTEweiIgc3R5bGU9ImZpbGw6IzRkNGQ0ZCIvPjxyZWN0IHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgeD0iMS41IiB5PSIuNSIgcng9IjIuNDMiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48L2c+PC9zdmc+)}.scylla-icon--glossary{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTIuNSAyLjVoMTN2MTZoLTEzeiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTE1LjU4IDE3LjIxaDEuOTJWLjVoLTEzYTIuMzQgMi4zNCAwIDAgMC0yIDIiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik00LjggMTMuOTNhMSAxIDAgMCAwIC43NS0uNDMgNiA2IDAgMCAwIC41Mi0xLjA4bDIuODctNy4wN2guMzZsMi44OCA2Ljc5YTguOTIgOC45MiAwIDAgMCAuNzIgMS40Ny43Ni43NiAwIDAgMCAuNjguMzJ2LjMySDkuNHYtLjMyYTMuMjQgMy4yNCAwIDAgMCAuODMtLjExYy4xMy0uMDYuMi0uMTkuMi0uNDJhMS41OSAxLjU5IDAgMCAwLS4xLS40NmMwLS4xMi0uMS0uMjctLjE3LS40NGwtLjMzLS43OGgtMi45Yy0uMTkuNTEtLjMxLjg1LS4zNiAxYTIuMzggMi4zOCAwIDAgMC0uMTcuNzNjMCAuMTguMTIuMzIuMzcuNGEyLjU2IDIuNTYgMCAwIDAgLjY2LjA4di4zMkg0LjhabTQuODQtMi43Mi0xLjI0LTNoLS4xMWwtMS4xNiAzWiIgc3R5bGU9ImZpbGw6IzRkNGQ0ZCIvPjwvZz48L3N2Zz4=)}.scylla-icon--infoworld{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MTB9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJNMTIgMi41SDYuNVY2YzAgMyAuNTUgNy4xNyA1IDkuNXY0IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNNi40IDQuNDRoLTRTMi41NiAxMSA4LjUgMTNNMTguNSA0LjVsNC0uMDZzLS4wNiA2LjU2LTYgOC41NiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTEyIDIuNWg2LjVWNmMwIDIuOTQtLjQgNy4wOC01IDkuNXY0TTkuNSAxOS41aDZ2MmgtNnoiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik03LjUgMjEuNWgxMHYxaC0xMHoiIHN0eWxlPSJmaWxsOmdyYXk7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48L2c+PC9zdmc+)}.scylla-icon--integrations{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibTE0LjU2IDEyLjctMS4yNS0xLjU3LTEuMzEuNzZhNiA2IDAgMCAwLTEuNjUtMWwuMDgtMS40OS0yLS40LS41MyAxLjQ0YTUuNzMgNS43MyAwIDAgMC0xLjg3LjMxbC0uODgtMS4xOS0xLjc3IDFMMy45MiAxMmE2LjMgNi4zIDAgMCAwLTEuMjIgMS40MWwtMS41LS4zNS0uNzQgMS44NyAxLjM4LjhhNi4yMyA2LjIzIDAgMCAwIDAgMS44M2wtMS40MS43Mi42NCAxLjkxIDEuNTktLjI4YTcuNjMgNy42MyAwIDAgMCAuNDguNjggNS44NiA1Ljg2IDAgMCAwIC42Ny43M2wtLjYyIDEuNDYgMS43MiAxIDEtMS4yNGE2LjQ2IDYuNDYgMCAwIDAgMS43OS4zNWwuNDYgMS41MiAyLS4zdi0xLjZhNi40MyA2LjQzIDAgMCAwIDEuNjItLjg5bDEuMy44NUwxNC40MyAyMWwtMS0xLjJhNi4yNCA2LjI0IDAgMCAwIC42OC0xLjc1bDEuNTEtLjE5LjA1LTItMS41MS0uMjZhNi4wNyA2LjA3IDAgMCAwLS42Mi0xLjgxWm0tNS4zNSA1LjUxYTEuOTMgMS45MyAwIDEgMSAuMzEtMi43MSAxLjkyIDEuOTIgMCAwIDEtLjMxIDIuNzFaIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtMjQuMzEgOC4wNS0uMTMtMS42NS0xLjI1LS4wOWE1LjI2IDUuMjYgMCAwIDAtLjY3LTEuNDRsLjc1LTEtMS4xNi0xLjE3LTEgLjc0YTUuMTggNS4xOCAwIDAgMC0xLjQzLS42NmwtLjA2LTEuMjQtMS42NS0uMTctLjMyIDEuMjVhNS43NyA1Ljc3IDAgMCAwLTEuNTIuMzhMMTUgMi4xbC0xLjM3LjkuNTggMS4xOGE0Ljg4IDQuODggMCAwIDAtLjg2IDEuMjVsLTEuMy0uMTYtLjQ1IDEuNiAxLjIyLjU1YTUuMTcgNS4xNyAwIDAgMCAwIC42OEE0LjI4IDQuMjggMCAwIDAgMTMgOWwtMS4xMS43Mi42OSAxLjUxIDEuMjgtLjM3YTQuOTQgNC45NCAwIDAgMCAxLjA3IDEuMDdsLS4zOSAxLjI2IDEuNS43MS43NC0xLjA5YTUuMDcgNS4wNyAwIDAgMCAxLjUyLjE0bC41IDEuMTkgMS42MS0uNDEtLjEzLTEuMjlhNS4xNCA1LjE0IDAgMCAwIDEuMjctLjg4bDEuMTIuNTcgMS0xLjM1LS45MS0uODhhNC45IDQuOSAwIDAgMCAuNDItMS41MlptLTYuMiAxLjQzYTEuNzQgMS43NCAwIDEgMSAxLjYtMS44NiAxLjc0IDEuNzQgMCAwIDEtMS42IDEuODZaIiBjbGFzcz0iY2xzLTEiLz48L2c+PC9zdmc+)}.scylla-icon--knowledge-base{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMSAxOSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTojNGQ0ZDRkfS5jbHMtMXtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9LmNscy0ye3N0cm9rZS1taXRlcmxpbWl0OjEwfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJMYXllcl81IiBkYXRhLW5hbWU9IkxheWVyIDUiPjxwYXRoIGQ9Ik0xNi4yMSA2LjM4YTUuMzYgNS4zNiAwIDAgMS0xLjUxIDMuNzMgNSA1IDAgMCAwLTEuNDUgMy4zMUg4LjQ3YTUuNDEgNS40MSAwIDAgMC0xLjI4LTMuMTEgNS4zNyA1LjM3IDAgMSAxIDktMy45M1pNMTMuMjMgMTUuNjdIOC40NSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTEzLjI0IDEzLjRoLTQuOHY0LjE2YS43LjcgMCAwIDAgLjcxLjdoMy4zOGEuNy43IDAgMCAwIC43MS0uN1oiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik0xMC44NCA4LjIxYTEuNjUgMS42NSAwIDEgMSAxLjY0LTEuNjUgMS42NSAxLjY1IDAgMCAxLTEuNjQgMS42NVpNMTAuODQgOC42N3Y0LjY0IiBjbGFzcz0iY2xzLTIiLz48L2c+PC9zdmc+)}.scylla-icon--less{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNyIgaGVpZ2h0PSIxNyIgZmlsbD0ibm9uZSI+PHJlY3Qgd2lkdGg9IjE3IiBoZWlnaHQ9IjE3IiBmaWxsPSIjQjNCQUM1IiByeD0iMSIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMyA4LjVhMSAxIDAgMCAxLTEgMUg1YTEgMSAwIDAgMSAwLTJoN2ExIDEgMCAwIDEgMSAxWiIvPjwvc3ZnPg==);filter:none}.scylla-icon--live-test{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtNntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLWxpbmVjYXA6cm91bmR9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48Y2lyY2xlIGN4PSIxMi41IiBjeT0iMTUiIHI9IjkuNSIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjVweDtzdHJva2UtbWl0ZXJsaW1pdDoxMDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXkiLz48cGF0aCBkPSJNMTAgLjVoNXYyaC01eiIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjFweDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7ZmlsbDpub25lO3N0cm9rZTpncmF5Ii8+PHBhdGggZD0iTTUuOCA4LjIgNC4xMyA2LjUzbDEuOC0xLjgxTDcuNiA2LjQiIHN0eWxlPSJzdHJva2Utd2lkdGg6MS4xMXB4O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbGluZWNhcDpyb3VuZDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXkiLz48cGF0aCBkPSJNMTIgNlYyLjUiIHN0eWxlPSJzdHJva2Utd2lkdGg6MS4xM3B4O3N0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6bm9uZTtzdHJva2U6Z3JheSIvPjxwYXRoIGQ9Ik0xMyA2VjIuNSIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjA4cHg7c3Ryb2tlLW1pdGVybGltaXQ6MTA7ZmlsbDpub25lO3N0cm9rZTpncmF5Ii8+PHBhdGggZD0iTTEyLjUgOC4wNlYxME0xMi41IDIwLjA0djEuODhNNy4xMyAxMC4wOGwxLjc5IDEuODhNMTYuMDQgMTcuMDhsMiAxLjg4TTcgMTguOTJsMS44OC0xLjg4TTE2LjEzIDExLjk2bDEuNzktMS44MyIgY2xhc3M9ImNscy02Ii8+PGVsbGlwc2UgY3g9IjEyLjUiIGN5PSIxNC4zNiIgcng9IjEuNSIgcnk9IjEuMzYiIHN0eWxlPSJmaWxsOmdyYXkiLz48cGF0aCBkPSJtMTIuNjMgMTQuNTQgMi41IDYuMzgiIGNsYXNzPSJjbHMtNiIvPjwvZz48L3N2Zz4=)}.scylla-icon--mail-list{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItbWFpbCI+PHBhdGggZD0iTTQgNGgxNmMxLjEgMCAyIC45IDIgMnYxMmMwIDEuMS0uOSAyLTIgMkg0Yy0xLjEgMC0yLS45LTItMlY2YzAtMS4xLjktMiAyLTJ6Ii8+PHBhdGggZD0ibTIyIDYtMTAgN0wyIDYiLz48L3N2Zz4=)}.scylla-icon--manager{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtM3tmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDouOTdweH0uY2xzLTR7ZmlsbDpncmF5fTwvc3R5bGU+PC9kZWZzPjxwYXRoIGlkPSJDYWxxdWVfMiIgZD0iTTE4IDJoNXYyMkgzVjJoNC45MiIgZGF0YS1uYW1lPSJDYWxxdWUgMiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQiLz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik04IDBoMTB2NEg4eiIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjA3cHg7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZCIvPjxwYXRoIGQ9Ik03IDloM3YzSDd6TTcgMTZoM3YzSDd6IiBjbGFzcz0iY2xzLTMiLz48cGF0aCBkPSJNMTIuNSA5LjVoN3YyaC03ek0xMi41IDE2LjVoN3YyaC03eiIgY2xhc3M9ImNscy00Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--memory-management{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZH0uY2xzLTJ7c3Ryb2tlLXdpZHRoOjEuMTNweH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxyZWN0IHdpZHRoPSIxNSIgaGVpZ2h0PSIxNSIgeD0iNS41IiB5PSI1LjUiIGNsYXNzPSJjbHMtMSIgcng9IjIuNzQiIHJ5PSIyLjc0Ii8+PHBhdGggZD0iTTkuNSA5LjVoN3Y3aC03eiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTguNSA1LjV2LTRNMTEuNSA1LjV2LTRNMTQuNSA1LjV2LTRNMTcuNSA1LjV2LTRNOC41IDI0LjV2LTRNMTEuNSAyNC41di00TTE0LjUgMjQuNXYtNE0xNy41IDI0LjV2LTRNMjAuNSA4LjVoNE0yMC41IDExLjVoNE0yMC41IDE0LjVoNE0yMC41IDE3LjVoNE0xLjUgOC41aDRNMS41IDExLjVoNE0xLjUgMTQuNWg0TTEuNSAxNy41aDQiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.scylla-icon--monitoring{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGcgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTUuNTUgMTAuODlhMy44MyAzLjgzIDAgMCAxLS4xNS0zLjc2IiBzdHlsZT0ic3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZTpncmF5O2ZpbGw6bm9uZSIvPjxyZWN0IHdpZHRoPSIzLjA1IiBoZWlnaHQ9IjEwLjgiIHg9IjE3LjYzIiB5PSIxNC4wMSIgcng9Ii41NyIgcnk9Ii41NyIgc3R5bGU9InN0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6Z3JheTtzdHJva2Utd2lkdGg6Ljk1cHg7c3Ryb2tlOmdyYXkiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxOS4xNTggMTkuNDA1KSIvPjxjaXJjbGUgY3g9IjguNSIgY3k9IjkiIHI9IjciIHN0eWxlPSJzdHJva2Utd2lkdGg6MnB4O3N0cm9rZS1taXRlcmxpbWl0OjEwO3N0cm9rZTpncmF5O2ZpbGw6bm9uZSIvPjxwYXRoIGQ9Im0xNi4wNSAxNi4zOS0yLjI4LTIuMjgiIHN0eWxlPSJzdHJva2UtbWl0ZXJsaW1pdDoxMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2U6Z3JheTtmaWxsOm5vbmUiLz48L2c+PC9zdmc+)}.scylla-icon--networking{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTB9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48Y2lyY2xlIGN4PSIxMi41IiBjeT0iMTIuNSIgcj0iNCIgc3R5bGU9InN0cm9rZS13aWR0aDouOTRweDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48Y2lyY2xlIGN4PSI1IiBjeT0iMyIgcj0iMi41IiBjbGFzcz0iY2xzLTIiLz48Y2lyY2xlIGN4PSIxOSIgY3k9IjIwIiByPSIyLjUiIGNsYXNzPSJjbHMtMiIvPjxjaXJjbGUgY3g9IjIyIiBjeT0iNi42IiByPSIyLjUiIGNsYXNzPSJjbHMtMiIvPjxjaXJjbGUgY3g9IjQuNSIgY3k9IjIyIiByPSIyLjUiIGNsYXNzPSJjbHMtMiIvPjxwYXRoIGQ9Im02LjgzIDUuNSAzLjI1IDQuMzNNMjAuMjMgNy44NSAxNS4zMyAxMU05LjgzIDE1LjA4bC00LjA5IDUuODRNMTQuNTggMTUuMzNsMyAzLjA5IiBjbGFzcz0iY2xzLTIiLz48Y2lyY2xlIGN4PSIxMi41IiBjeT0iMTIuNSIgcj0iMS41IiBzdHlsZT0iZmlsbDpncmF5Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--news{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTMgMTUuMTcgMTYuMzEgMy44MmExLjQ4IDEuNDggMCAwIDEgMi4yMi40Nmw1LjE1IDkuNjVhMS40NiAxLjQ2IDAgMCAxLS45MyAyLjEyTDUuNjkgMTkuOVpNOC43MSAxOS4zM2wuNzYgMi4yMmExLjUxIDEuNTEgMCAwIDAgMS44NSAxbDMuNTgtMS4wNmExLjUgMS41IDAgMCAwIDEtMS44NkwxNS40NSAxOE01LjU0IDIwbC0xLjgzIDFhLjkyLjkyIDAgMCAxLTEuMjUtLjM3TC42MSAxNy40OUEuOTIuOTIgMCAwIDEgMSAxNi4yNGwxLjgzLTFNOC41IDE0bDcuMzgtNS41IiBjbGFzcz0iY2xzLTEiLz48L3N2Zz4=)}.scylla-icon--newsletter{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1taXRlcmxpbWl0OjEwfS5jbHMtMntzdHJva2UtbGluZWNhcDpyb3VuZH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzQiIGRhdGEtbmFtZT0iQ2FscXVlIDQiPjxwYXRoIGQ9Ik0xOS41IDkuNWgzdjEyaC0yMHYtMTJoMyIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTIuNjUgOS44NCA5Ljg1IDYuODggOC42My02Ljg4IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtNS41IDcuNS0zIDJNMTQuMzUgMy44NmwtMS40Ni0xLjA5LTEuNDcgMS4wOU0yMS41IDkuNWwtMi0yTTE5LjUgMTEuNXYtN2gtMTR2Ny40NyIgY2xhc3M9ImNscy0yIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--nsql-guides{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGcgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHJlY3Qgd2lkdGg9IjEuMTUiIGhlaWdodD0iOS43MiIgeD0iNC4zNyIgeT0iMTMuNzEiIHJ4PSIuNTQiIHJ5PSIuNTQiIHN0eWxlPSJzdHJva2U6Z3JheTtzdHJva2UtbWl0ZXJsaW1pdDoxMDtmaWxsOmdyYXk7c3Ryb2tlLXdpZHRoOjEuMDlweCIgdHJhbnNmb3JtPSJyb3RhdGUoNDUgNC45NDggMTguNTcpIi8+PGNpcmNsZSBjeD0iMTIuMjUiIGN5PSIxMi4yNSIgcj0iNC43NSIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjVweDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLW1pdGVybGltaXQ6MTAiLz48cGF0aCBkPSJNOC41IDIwLjV2M2gxNXYtMjFoLTE1djIiIHN0eWxlPSJzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2Utd2lkdGg6MS4wNnB4O2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbWl0ZXJsaW1pdDoxMCIvPjwvZz48L3N2Zz4=)}.scylla-icon--open-source{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfS5jbHMtMntmaWxsOmdyYXl9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJNLjMxIDIxLjUxIDUgMTkuNjlhMi4zNyAyLjM3IDAgMCAxIDEuODguMTlsNS4yNCAxLjY4YTIuMjMgMi4yMyAwIDAgMCAyLS4xMmw5LjUtNC43NWMuOC0uNDQgMS42NC0xLjMxIDEuMTMtMS45MWEyLjM0IDIuMzQgMCAwIDAtMi42NC0uNDJMMTggMTYuMDkiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Im0uMjUgMTUuNjkgNC44OC0xLjIxYzEuMjUtLjMgMi4xNy0uNjMgMy40NC0uMTNhMTUuMjEgMTUuMjEgMCAwIDAgNCAxLjFoNC41MmMuODUgMCAuOTUuNTQuOTUgMS4xM2ExIDEgMCAwIDEtMS4wOCAxIDY1Ljg2IDY1Ljg2IDAgMCAxLTctLjMxIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNOC41NiA5LjY4di0uODFjMC0uOTEtLjM4LTEuMjEtMS4yOS0xLjIxSDdWNi4zaC4zMWMuOTEgMCAxLjI5LS4zIDEuMjktMS4yMXYtLjgxYzAtMS4yLjY2LTEuOTIgMi44Mi0yLjN2MS4xNmMtMS4yNC4zNS0xLjQzLjY4LTEuNDMgMS40di44N0ExLjUyIDEuNTIgMCAwIDEgOC43NSA3IDEuNTIgMS41MiAwIDAgMSAxMCA4LjU2di44N2MwIC43MS4xOSAxIDEuNDMgMS40VjEyYy0yLjIxLS4zNS0yLjg3LTEuMTItMi44Ny0yLjMyWk0xNy40MyA0LjN2LjgxYzAgLjkxLjM3IDEuMjEgMS4yOSAxLjIxSDE5djEuMzZoLS4zMWMtLjkyIDAtMS4yOS4zLTEuMjkgMS4yMXYuODFjMCAxLjItLjY1IDItMi44MSAyLjM1di0xLjJjMS4yNS0uMzYgMS40NC0uNjkgMS40NC0xLjR2LS44N0ExLjUzIDEuNTMgMCAwIDEgMTcuMjUgNyAxLjUzIDEuNTMgMCAwIDEgMTYgNS40M3YtLjg3YzAtLjcyLS4xOS0xLTEuNDQtMS40VjJjMi4yMi4zOCAyLjg3IDEuMSAyLjg3IDIuM1oiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.scylla-icon--operator{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjQuODEgMS4wMSAyOC4zMiAyNy42NCI+PHBhdGggZD0iTTMyLjUyIDE4cy0uMDkgMC0uMDktLjA1LS4wOCAwLS4xNyAwYTIuMTkgMi4xOSAwIDAgMC0uNTEgMCAuNDcuNDcgMCAwIDEtLjI2LS4wNSA5LjI5IDkuMjkgMCAwIDEtMS40OS0uMzIuNTQuNTQgMCAwIDEtLjMtLjMxbC0uMzQtLjA4YTExLjI1IDExLjI1IDAgMCAwLS4xOC0zLjc5IDExLjU1IDExLjU1IDAgMCAwLTEuNS0zLjUybC4yNi0uMjZhLjU5LjU5IDAgMCAxIC4xMy0uMzkgNy43MyA3LjczIDAgMCAxIDEuMi0uODZsLjI2LS4xMy40Ny0uM3MuMDkgMCAuMTMtLjA4IDAtLjA1IDAtLjA5YS44NC44NCAwIDAgMCAuMTctMS4yLjc4Ljc4IDAgMCAwLS42LS4zIDEgMSAwIDAgMC0uNi4yMWMtLjA1LjA1LS4wOS4wOS0uMTMuMDlhMy4wOCAzLjA4IDAgMCAwLS4zNS4zOWMwIC4wOC0uMTMuMTMtLjE3LjE3YTUuNjQgNS42NCAwIDAgMS0xLjA3Ljk0LjU4LjU4IDAgMCAxLS4yNi4wOS4yNS4yNSAwIDAgMS0uMTcgMGgtLjA1bC0uMzQuMjEtMS4wOC0xYTExIDExIDAgMCAwLTUuNjUtMi4yN3YtLjM0YS42LjYgMCAwIDEtLjIyLS4zNEE4LjE4IDguMTggMCAwIDEgMTkuNjYgM3YtLjI1YzAtLjA4LjA1LS4zNS4wOS0uNTJ2LS4zMWEuODIuODIgMCAwIDAtMS40Ni0uNi44Ni44NiAwIDAgMC0uMjYuNnYuMjJhMS44MiAxLjgyIDAgMCAwIC4wOS41MS41OS41OSAwIDAgMSAwIC4yNlYzYTguODIgOC44MiAwIDAgMSAuMDggMS40Ny41OS41OSAwIDAgMS0uMjEuMzRWNS4yNGMtLjQ4IDAtMSAuMTMtMS40Ny4yMmExMC4xNiAxMC4xNiAwIDAgMC01LjI4IDNMMTEgOC4yNGgtLjE3YS43My43MyAwIDAgMS0uMjYtLjA5IDcuOCA3LjggMCAwIDEtMS4wNy0xYzAtLjA4LS4xMy0uMTMtLjE3LS4xN3MtLjI1LS4yLS4zMy0uMzMtLjA4IDAtLjEzLS4wOHYtLjA1YTEgMSAwIDAgMC0uNi0uMjEuNjQuNjQgMCAwIDAtLjYuMy45MS45MSAwIDAgMCAuMTcgMS4yczAgLjA1IDAgLjA1LjA5LjA4LjEzLjA4YTUgNSAwIDAgMCAuNDcuMjZsLjI2LjEzYTYuNjEgNi42MSAwIDAgMSAxLjIxLjg2LjQ3LjQ3IDAgMCAxIC4xMy4zOXYtLjA1bC4yNS4yNmEyLjUzIDIuNTMgMCAwIDEtLjEzLjIyIDEwLjIgMTAuMiAwIDAgMC0xLjUgN2wtLjM1LjA5YzAgLjEzLS4xNy4yMS0uMy4zYTguNTYgOC41NiAwIDAgMS0xLjQ2LjI2LjU5LjU5IDAgMCAwLS4yNiAwaC0uNTJjLS4xOCAwLS4wOC4wNS0uMTcuMDVoLS4wOGEuODQuODQgMCAwIDAtLjY5IDEgLjc5Ljc5IDAgMCAwIC44Ni42LjM5LjM5IDAgMCAwIC4yMSAwSDYuMTJhMy42MSAzLjYxIDAgMCAwIC40Ny0uMTcuNjUuNjUgMCAwIDEgLjI2LS4wOCA3LjY1IDcuNjUgMCAwIDEgMS40Mi0uMzkuNDkuNDkgMCAwIDEgLjM1LjEzaC4zOWExMC4zMiAxMC4zMiAwIDAgMCAzLjUzIDUgNi4zMSA2LjMxIDAgMCAwIDEuMTYuNzdsLS4yMi4zYS41MS41MSAwIDAgMSAwIC40MyA2LjU0IDYuNTQgMCAwIDEtLjY5IDEuMjR2LjA1YS43OC43OCAwIDAgMS0uMTcuMjFjLS4wOS4wOS0uMTcuMjYtLjMuNDNzMCAuMDktLjA5LjEzIDAgLjA1IDAgLjA1YS44OC44OCAwIDAgMCAuMzQgMS4xNi45LjkgMCAwIDAgLjMuMDggMSAxIDAgMCAwIC44Mi0uNTFzMC0uMDguMDktLjEzLjEzLS4zLjE3LS40N2wuMDktLjI2YTcuMDcgNy4wNyAwIDAgMSAuNTYtMS4zMy42Mi42MiAwIDAgMSAuMzQtLjI2bC4xNy0uMzVhMTAuMDUgMTAuMDUgMCAwIDAgMy43NS42OSA4LjQ1IDguNDUgMCAwIDAgMi4zMi0uMyAxMS40NiAxMS40NiAwIDAgMCAxLjM3LS4zOWwuMTguMzFhLjYyLjYyIDAgMCAxIC4zNC4yNiA3LjA3IDcuMDcgMCAwIDEgLjU2IDEuMzNsLjA5LjI2YTEuMzEgMS4zMSAwIDAgMCAuMTcuNDdjMCAuMDUgMCAuMDkuMDkuMTNhMSAxIDAgMCAwIC44Mi41MSAxLjA1IDEuMDUgMCAwIDAgLjM0LS4wOC43Ni43NiAwIDAgMCAuMzktLjQ4IDEuMDggMS4wOCAwIDAgMC0uMDUtLjY0LjIuMiAwIDAgMC0uMDgtLjEzIDEuNTMgMS41MyAwIDAgMC0uMzEtLjQzLjY1LjY1IDAgMCAwLS4xNy0uMjJ2LS4wOWE1LjIyIDUuMjIgMCAwIDEtLjY5LTEuMjQuNTEuNTEgMCAwIDEgLjA1LS40M2wtLjEzLS4zNEExMC42OCAxMC42OCAwIDAgMCAyOSAxOC44MmwuMzQuMDV2LS4wNWEuNTQuNTQgMCAwIDEgLjM1LS4xMyA3LjgyIDcuODIgMCAwIDEgMS4zOC4zOS42Mi42MiAwIDAgMCAuMjYuMDkgMi40MiAyLjQyIDAgMCAwIC40Ny4yMXMuMDkgMCAuMTcgMGguMDlhLjM5LjM5IDAgMCAwIC4yMSAwIC45NC45NCAwIDAgMCAuODYtLjYgMSAxIDAgMCAwLS43Ny0uOVptLTEyLjQzLTEuMzMtMS4xNi41Ni0xLjE2LS41Ni0uMy0xLjI1LjgxLTFoMS4yOWwuODIgMVptNy0yLjc5YTggOCAwIDAgMSAuMTcgMi43MWwtNC4xNS0uNzVjLS4zOC0uMDgtLjY4LS45LS43MS0xLjIyYTQgNCAwIDAgMSAuMjEtLjc0bDMuNDUtMi41NGE4LjU4IDguNTggMCAwIDEgMS4wNCAyLjU0Wm0tMi4zMS00LjEzLTMuMjIgMi42OWExLjI4IDEuMjggMCAwIDEtMS4yNS0uMzdjLS4wOS0uMDktLjM3LS4yNS0uMzctLjM4VjcuNDNhOC4wNyA4LjA3IDAgMCAxIDQuODYgMi4zMlpNMTcgNy41NmwxLS4xOC0uMDYgNC4zMWMwIC4zOC0uNjQuNjgtMSAuNjhhMS4xMSAxLjExIDAgMCAxLS4zNS0uMDhMMTMgOS43NWE4LjQxIDguNDEgMCAwIDEgNC0yLjE5Wm0tNS4yNCAzLjc4IDMuMzcgMi40Ny4zMi41M2ExLjE0IDEuMTQgMCAwIDEtLjI1IDEgLjc4Ljc4IDAgMCAxLS4zOC4zMWwtNC4zMS45YTkgOSAwIDAgMSAxLjI0LTUuMjFaTTExIDE4LjYxbDQuMS0xLjIzYy4zNSAwIC44NC43MS44OSAxLjA2YS41MS41MSAwIDAgMS0uMDUuNDNsLTEuNjMgMy45NUE4LjQxIDguNDEgMCAwIDEgMTEgMTguNjFabTkuNzYgNS4zM2E4LjY3IDguNjcgMCAwIDEtMS44NS4yMSA5LjU5IDkuNTkgMCAwIDEtMi43MS0uNDNsMS42Ni00Yy4yMS0uMjYgMS0uMiAxLjMxIDBhMi40OCAyLjQ4IDAgMCAxIC4zNC4zbDIuMDcgMy43NGE1LjcyIDUuNzIgMCAwIDAtLjguMThaTTI2IDIwLjJhOC4zNiA4LjM2IDAgMCAxLTIuNTggMi41OGwtMS45Mi0zLjcyYTEuMTUgMS4xNSAwIDAgMSAuNDEtMWMuMjEtLjI1LjU5LS41OS43MS0uNTlsNC4yMiAxLjA2QTYuMjcgNi4yNyAwIDAgMSAyNiAyMC4yWiIgZGF0YS1uYW1lPSJDYWxxdWUgMiIgc3R5bGU9ImZpbGw6IzRkNGQ0ZCIvPjwvc3ZnPg==)}.scylla-icon--overview{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTIyLjYxIDMuNDVDMjIuNjEgNS4wNiAxOCA2LjUgMTIuNSA2LjVzLTEwLTEuNDQtMTAtMyA0LjUtMyAxMC0zIDEwLjExIDEuMzMgMTAuMTEgMi45NVpNMjIuNjEgOS40NGMwIDEuNjEtNC42NCAzLjA2LTEwLjExIDMuMDZzLTEwLTEuNDUtMTAtMy4wNk0yMi42MSAxNS41MWMwIDEuNjItNC42NCAzLTEwLjExIDNzLTEwLTEuMzctMTAtM00yMi42MSAyMS41OWMwIDEuNjItNC42NCAyLjkxLTEwLjExIDIuOTFzLTEwLTEuMjktMTAtMi45MU0yLjUgMjEuNDdWMy40NU0yMi41IDIxLjQ3VjMuNDUiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--partners{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTE4LjUgOC4yNmgtNC43MmwtMS4yMyAxLjI3TTIuMzkgMTUuMDkuMTUgMTMuNzRsNC44Ny04LjQyIDIuMjQgMS4zNC00Ljg3IDguNDN6TTIyLjU5IDE1LjA5bDIuMjQtMS4zNS00Ljg2LTguNDItMi4yNCAxLjM0IDQuODYgOC40M3pNMTAuNzEgMTUuMjZsLTIuOTMgMi4yMU0xMi4xOCAxNi40bC0yLjkzIDIuMjFNMTMuNjggMTcuNTNsLTIuOTMgMi4yMiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTYuMzggOC4zaDMuNzhhMi4yNyAyLjI3IDAgMCAxIDEuMzcuNDdjMS4yNiAxIDQuMDkgMy4xOCA0LjQ4IDMuNTZzLTEuMTQgMS42OC0yLjI3IDEuMWExOC4zNCAxOC4zNCAwIDAgMC0yLjExLS45Mi41Ny41NyAwIDAgMC0uNTYuMDlsLTQuNzkgMy44OUwxMi4zMyAyMWw5LjQ2LTcuMDlNMy4yNCAxNC4yMmwzLjQgMS44NSIgY2xhc3M9ImNscy0xIi8+PC9zdmc+)}.scylla-icon--plus{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNyIgaGVpZ2h0PSIxNyIgZmlsbD0ibm9uZSI+PHJlY3Qgd2lkdGg9IjE3IiBoZWlnaHQ9IjE3IiBmaWxsPSIjQjNCQUM1IiByeD0iMSIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNSA1YTEgMSAwIDEgMC0yIDB2Mi41SDVhMSAxIDAgMSAwIDAgMmgyLjVWMTJhMSAxIDAgMSAwIDIgMFY5LjVIMTJhMSAxIDAgMSAwIDAtMkg5LjVWNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==);filter:none}.scylla-icon--pricing{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfMiIgZGF0YS1uYW1lPSJDYWxxdWUgMiI+PHBhdGggZD0ibTIxLjczIDctMi40MS01LjEyYTIuNTIgMi41MiAwIDAgMC0yLjgyLTFsLTYuMDggMi4wNEExLjY5IDEuNjkgMCAwIDAgOS41MSA0TDMuOTMgMTkuMjlhMS4wNiAxLjA2IDAgMCAwIC42NCAxLjE3bDEwLjM0IDMuNzZhMSAxIDAgMCAwIDEuMjItLjQzbDUuNTgtMTUuMzNBMS44NyAxLjg3IDAgMCAwIDIxLjczIDdaIiBjbGFzcz0iY2xzLTEiLz48Y2lyY2xlIGN4PSIxNS43MyIgY3k9IjUuODkiIHI9IjIiIGNsYXNzPSJjbHMtMSIvPjx0ZXh0IHN0eWxlPSJmb250LXNpemU6MTJweDtmaWxsOmdyYXk7Zm9udC1mYW1pbHk6Um9ib3RvLU1lZGl1bSxSb2JvdG8iIHRyYW5zZm9ybT0icm90YXRlKDIwIC00OC4yNDQgMzAuNjcpIj4kPC90ZXh0PjwvZz48L3N2Zz4=)}.scylla-icon--release-note{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDouOTFweH08L3N0eWxlPjwvZGVmcz48ZyBpZD0iQ2FscXVlXzIiIGRhdGEtbmFtZT0iQ2FscXVlIDIiPjxwYXRoIGQ9Ik0yMS41IDI0LjVoLTE3VjUuN0w4Ljk1LjU0IDIxLjUuNXYyNHoiIHN0eWxlPSJzdHJva2Utd2lkdGg6LjlweDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kIi8+PHBhdGggZD0iTTQuNjUgNS41SDkuNVYxTTcuNSA4LjVoMTFNNy41IDExLjVoMTFNNy41IDE0LjVoMTFNNy41IDE3LjVoMTFNNy41IDIwLjVoMTEiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.scylla-icon--resource-center{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfS5jbHMtMntmaWxsOmdyYXl9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkNhbHF1ZV80IiBkYXRhLW5hbWU9IkNhbHF1ZSA0Ij48cGF0aCBkPSJNNS41IDIuNWg2LjkxbC4wOSAyMGgtN3YtMjB6IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNOCA0aDJ2MTAuOTdMOCAxNVY0eiIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTUuMzYgMi4yOSAyLjUgMy41djE4bDIuNzkgMS4xNCIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTEyLjU3IDIxLjg2IDEuNTcuNzUiIHN0eWxlPSJzdHJva2Utd2lkdGg6LjY4cHg7ZmlsbDpub25lO3N0cm9rZTpncmF5O3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZCIvPjxwYXRoIGQ9Im0xNC4xMSAyLjUtMS41NC41NyIgc3R5bGU9InN0cm9rZS13aWR0aDouODVweDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kIi8+PGNpcmNsZSBjeD0iOSIgY3k9IjE5IiByPSIxIiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMTQuNSAyLjVoNi45NGwuMDYgMjBoLTd2LTIweiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTE3IDRoMnYxMC45N0wxNyAxNVY0eiIgY2xhc3M9ImNscy0yIi8+PGNpcmNsZSBjeD0iMTgiIGN5PSIxOSIgcj0iMSIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTEyLjYgMi43M2gxLjY3VjIyLjZIMTIuNnpNMi41OCAyMS41bDIuNzUgMS4xVjIuNzNsLTIuNjYuOTQtLjA5IDE3LjgzeiIgY2xhc3M9ImNscy0yIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--roadmap{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTpncmF5fS5jbHMtMXtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOi45OHB4fS5jbHMtMntzdHJva2UtbWl0ZXJsaW1pdDoxMH0uY2xzLTN7ZmlsbDpncmF5fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibS41IDQuNSA4LTMgOCA0IDgtM3YxN2wtOCAzLTgtNC04IDN2LTE3ek04LjUgMS41VjE4TTE2LjUgNS41VjIyIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNMi41IDEzIDcgMTYuNU03IDEybC00LjUgNS41TTE4LjUgOGw0LjUgMy41TTIzIDdsLTQuNSA1LjUiIGNsYXNzPSJjbHMtMiIvPjxwYXRoIGQ9Ik0xMCAxM2gxdjFoLTF6TTEyIDEyaDF2MWgtMXpNMTQgMTFoMXYxaC0xeiIgY2xhc3M9ImNscy0zIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--search{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTEwLjUgMThhNy41IDcuNSAwIDEgMCAwLTE1IDcuNSA3LjUgMCAwIDAgMCAxNVpNMjEgMjFsLTUuMi01LjIiLz48L3N2Zz4=)}.scylla-icon--slack{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tISBGb250IEF3ZXNvbWUgUHJvIDYuMC4wIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlIChDb21tZXJjaWFsIExpY2Vuc2UpIENvcHlyaWdodCAyMDIyIEZvbnRpY29ucywgSW5jLi0tPjxwYXRoIGQ9Ik05NC4xMiAzMTUuMWMwIDI1LjktMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDZTMCAzNDEgMCAzMTUuMWMwLTI1LjkgMjEuMTYtNDcuMDYgNDcuMDYtNDcuMDZoNDcuMDZ2NDcuMDZ6bTIzLjcyIDBjMC0yNS45IDIxLjE2LTQ3LjA2IDQ3LjA2LTQ3LjA2czQ3LjA2IDIxLjE2IDQ3LjA2IDQ3LjA2djExNy44NGMwIDI1LjktMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDZzLTQ3LjA2LTIxLjE2LTQ3LjA2LTQ3LjA2VjMxNS4xem00Ny4wNi0xODguOThjLTI1LjkgMC00Ny4wNi0yMS4xNi00Ny4wNi00Ny4wNlMxMzkgMzIgMTY0LjkgMzJzNDcuMDYgMjEuMTYgNDcuMDYgNDcuMDZ2NDcuMDZIMTY0Ljl6bTAgMjMuNzJjMjUuOSAwIDQ3LjA2IDIxLjE2IDQ3LjA2IDQ3LjA2cy0yMS4xNiA0Ny4wNi00Ny4wNiA0Ny4wNkg0Ny4wNkMyMS4xNiAyNDMuOTYgMCAyMjIuOCAwIDE5Ni45czIxLjE2LTQ3LjA2IDQ3LjA2LTQ3LjA2SDE2NC45em0xODguOTggNDcuMDZjMC0yNS45IDIxLjE2LTQ3LjA2IDQ3LjA2LTQ3LjA2IDI1LjkgMCA0Ny4wNiAyMS4xNiA0Ny4wNiA0Ny4wNnMtMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDZoLTQ3LjA2VjE5Ni45em0tMjMuNzIgMGMwIDI1LjktMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDYtMjUuOSAwLTQ3LjA2LTIxLjE2LTQ3LjA2LTQ3LjA2Vjc5LjA2YzAtMjUuOSAyMS4xNi00Ny4wNiA0Ny4wNi00Ny4wNiAyNS45IDAgNDcuMDYgMjEuMTYgNDcuMDYgNDcuMDZWMTk2Ljl6TTI4My4xIDM4NS44OGMyNS45IDAgNDcuMDYgMjEuMTYgNDcuMDYgNDcuMDYgMCAyNS45LTIxLjE2IDQ3LjA2LTQ3LjA2IDQ3LjA2LTI1LjkgMC00Ny4wNi0yMS4xNi00Ny4wNi00Ny4wNnYtNDcuMDZoNDcuMDZ6bTAtMjMuNzJjLTI1LjkgMC00Ny4wNi0yMS4xNi00Ny4wNi00Ny4wNiAwLTI1LjkgMjEuMTYtNDcuMDYgNDcuMDYtNDcuMDZoMTE3Ljg0YzI1LjkgMCA0Ny4wNiAyMS4xNiA0Ny4wNiA0Ny4wNiAwIDI1LjktMjEuMTYgNDcuMDYtNDcuMDYgNDcuMDZIMjgzLjF6Ii8+PC9zdmc+)}.scylla-icon--stack-overflow{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIzMSIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMjEuOTQ5LjExMyAyLjA0MyAxMS42Ny0yLjUxNC40MzJMMTkuNDM1LjU0NSAyMS45NS4xMTRabS0xNy45NzMgMjYgMTEuOTQ1LS4wMDUtLjAwMi0yLjUzLTExLjk0NC4wMDYuMDAxIDIuNTNabTEyLjIzMi01Ljc3N0w0LjMxNSAxOS4yNWwtLjIzNSAyLjUyIDExLjg5NCAxLjA4NS4yMzQtMi41MTlabS0xMC43NS02LjM3NSAxMS41MzUgMy4wNzQtLjY2MiAyLjQ0My0xMS41MzUtMy4wNzUuNjYyLTIuNDQyWm0xMy4wNC4xOEw4LjIxMiA4LjEyNmwtMS4yOTcgMi4xNzggMTAuMjg5IDYuMDE3IDEuMjk2LTIuMTc4Wm0tNC4yMDYtMTEuNTYgNi43MyA5Ljc4Ny0yLjEwOCAxLjQyNC02LjczLTkuNzg1IDIuMTA4LTEuNDI1WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTE3Ljk1IDE3Ljc4OVYyOC4xM0gyLjI4MlYxNy43ODlILjI0M3YxMi4zMjZIMTkuOThWMTcuNzg5aC0yLjAzWiIvPjwvc3ZnPg==)}.scylla-icon--summit{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJDYWxxdWVfMSIgZGF0YS1uYW1lPSJDYWxxdWUgMSIgdmlld0JveD0iMCAwIDI1IDI1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6bm9uZTtzdHJva2U6IzRkNGQ0ZDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmR9PC9zdHlsZT48L2RlZnM+PHBhdGggZD0ibTE2LjUgMjIgMS02LjUtMTAgLjAzIDEgNi40MyIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTMuNDYgMTJBNS42OSA1LjY5IDAgMCAxIDUgNy41IiBzdHlsZT0ic3Ryb2tlLXdpZHRoOjEuMXB4O3N0cm9rZTojNGQ0ZDRkO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtmaWxsOm5vbmUiLz48cGF0aCBkPSJNMTQuNjIgNWEyLjMzIDIuMzMgMCAwIDEtMi4yNSAyLjVjLTEuMzMgMC0yLTEuMTItMS45NS0yLjQ0cy43LTIuNSAyLTIuNDhBMi4yNyAyLjI3IDAgMCAxIDE0LjYyIDVaTTE3LjU4IDEyYTMuMjMgMy4yMyAwIDAgMC0zLjQ2LTMuNUgxMUEzLjI2IDMuMjYgMCAwIDAgNy41IDEyIiBjbGFzcz0iY2xzLTEiLz48Y2lyY2xlIGN4PSI0Ljk0IiBjeT0iNi45NiIgcj0iMS4wMSIgc3R5bGU9ImZpbGw6IzRkNGQ0ZDtzdHJva2Utd2lkdGg6MS4xcHg7c3Ryb2tlOiM0ZDRkNGQ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kIi8+PHBhdGggZD0iTTcuNTQgMTguNUg0LjVsLTItNmgyMGwtMiA2aC0zIiBjbGFzcz0iY2xzLTEiLz48L3N2Zz4=)}.scylla-icon--support{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTE4LjE5IDcuNWExMCAxMCAwIDAgMSAuMjEgMi4wN2MwIDQuMzYtMi42MyA2LjkzLTUuOSA2Ljkzcy01Ljk0LTIuNTctNS45NC02LjkzYTEwLjUxIDEwLjUxIDAgMCAxIC4yMi0yLjEyIiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJNNy42NyAyLjIzQTYuNTggNi41OCAwIDAgMSAxMi41LjVhNS42NSA1LjY1IDAgMCAxIDQuMjkgMS43YzEuOTMgMS45NCAyLjM1IDUuMDcgMi40MyA2LjcyYTEuNDkgMS40OSAwIDAgMC0uNzkuMDUgOC42OCA4LjY4IDAgMCAwLS4wOC0xLjE2aDBhNS41MyA1LjUzIDAgMCAxLTEuNzctMi4zNEwxNi40OSA1bC0uMzguMjJBMTkgMTkgMCAwIDEgNi44IDcuMzhhLjUyLjUyIDAgMCAwLS40Mi4xNmMtLjIzLjI0LS4xNS42NS0uMDcgMS4wOCAwIC4xMSAwIC4yMi4wNS4zMmExLjQgMS40IDAgMCAwLS41OCAwYy0uMS0xLjQ1LS4wNi00LjY4IDEuODktNi43MVpNNi4zOCA5Yy0uNjUtLjA4LTEgLjEtMS4xNC43OWEyLjA2IDIuMDYgMCAwIDAgMS4zNyAyLjI5TTE4LjU2IDljLjY1LS4wOCAxLjA1LjEgMS4xNC43OWEyLjA2IDIuMDYgMCAwIDEtMS4zNyAyLjI5TTkuNSAxOC4yM1YxNS41TTE1LjUgMTUuNXYyLjczTTIuNSAyNC4xNmMuMjQtMiAuNTktMy42MyAyLjQzLTQuNDlhMjQuMjkgMjQuMjkgMCAwIDEgNC44Mi0xLjM3TTIyLjUgMjQuMzNjLS4yNC0yLS40Mi0zLjgtMi4yNi00LjY2YTI0LjI5IDI0LjI5IDAgMCAwLTQuODItMS4zNyIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTE1LjM5IDE4LjM5YTQuMzcgNC4zNyAwIDAgMS0yLjkxIDEuMDcgNC40MiA0LjQyIDAgMCAxLTIuODktMS4wNSIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTExIDEzaDN2MmgtM3oiIHN0eWxlPSJmaWxsOmdyYXkiLz48cGF0aCBkPSJNMTguMDcgMTJhOS4yMSA5LjIxIDAgMCAxLTUuNTMgMi4wNyIgc3R5bGU9InN0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6bm9uZTtzdHJva2U6Z3JheSIvPjwvZz48L3N2Zz4=)}.scylla-icon--tech-talks{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTguMzkgNC41SDIzLjV2MTNoLTE1IiBjbGFzcz0iY2xzLTEiLz48Y2lyY2xlIGN4PSI0LjUiIGN5PSI2LjUiIHI9IjIiIHN0eWxlPSJzdHJva2UtbWl0ZXJsaW1pdDoxMDtmaWxsOm5vbmU7c3Ryb2tlOmdyYXkiLz48cGF0aCBkPSJNMS41IDkuNWgybC44Ljg2LjctLjg2aDUuNThhMSAxIDAgMSAxIDAgMkg2LjV2MTAuODhhMSAxIDAgMCAxLTEgMS4xMiAxIDEgMCAwIDEtMS0xIDEgMSAwIDAgMS0xIDEgLjkzLjkzIDAgMCAxLTEtMXYtNmMtLjc4IDAtMi0uNDctMi0xdi01YTEgMSAwIDAgMSAxLTFaIiBjbGFzcz0iY2xzLTEiLz48L2c+PC9zdmc+)}.scylla-icon--testing{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTYuNSA2LjVoMTJ2MTJoLTEyeiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0iTTQuNSA0LjVoMTZ2MTZoLTE2eiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTguNSAxMC41IDUgNSAxMS0xMiIgY2xhc3M9ImNscy0xIi8+PC9nPjwvc3ZnPg==)}.scylla-icon--thumbs-up{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLXRodW1icy11cCI+PHBhdGggZD0iTTE0IDlWNWEzIDMgMCAwIDAtMy0zbC00IDl2MTFoMTEuMjhhMiAyIDAgMCAwIDItMS43bDEuMzgtOWEyIDIgMCAwIDAtMi0yLjN6TTcgMjJINGEyIDIgMCAwIDEtMi0ydi03YTIgMiAwIDAgMSAyLTJoMyIvPjwvc3ZnPg==)}.scylla-icon--thumbs-down{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLXRodW1icy1kb3duIj48cGF0aCBkPSJNMTAgMTV2NGEzIDMgMCAwIDAgMyAzbDQtOVYySDUuNzJhMiAyIDAgMCAwLTIgMS43bC0xLjM4IDlhMiAyIDAgMCAwIDIgMi4zem03LTEzaDIuNjdBMi4zMSAyLjMxIDAgMCAxIDIyIDR2N2EyLjMxIDIuMzEgMCAwIDEtMi4zMyAySDE3Ii8+PC9zdmc+)}.scylla-icon--tip{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTEyIDI0QzUuNCAyNCAwIDE4LjYgMCAxMlM1LjQgMCAxMiAwczEyIDUuNCAxMiAxMi01LjQgMTItMTIgMTJabTAtMjJDNi41IDIgMiA2LjUgMiAxMnM0LjUgMTAgMTAgMTAgMTAtNC41IDEwLTEwUzE3LjUgMiAxMiAyWiIvPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0xMSAxNmMtLjMgMC0uNS0uMS0uNy0uM2wtMy0zYy0uNC0uNC0uNC0xIDAtMS40LjQtLjQgMS0uNCAxLjQgMGwzIDNjLjQuNC40IDEgMCAxLjQtLjIuMi0uNC4zLS43LjNaIi8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTExIDE2Yy0uMyAwLS41LS4xLS43LS4zLS40LS40LS40LTEgMC0xLjRsNi02Yy40LS40IDEtLjQgMS40IDAgLjQuNC40IDEgMCAxLjRsLTYgNmMtLjIuMi0uNC4zLS43LjNaIi8+PC9zdmc+)}.scylla-icon--training{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfMiIgZGF0YS1uYW1lPSJDYWxxdWUgMiI+PHBhdGggZD0iTTE3LjUgMTUuNUguNXYtMTNoMThNNS41IDI1bDQtNC4zIDQgNC4zIiBjbGFzcz0iY2xzLTEiLz48Y2lyY2xlIGN4PSIyMSIgY3k9IjQiIHI9IjIuNSIgc3R5bGU9InN0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6bm9uZTtzdHJva2U6Z3JheSIvPjxwYXRoIGQ9Ik0yMy40MSA3LjVoLTEuNTJMMjEgOWwtLjktMS41SDEzQTEuOCAxLjggMCAwIDAgMTEuNSA5YTEuOCAxLjggMCAwIDAgMS41IDEuNWg0LjV2MTMuMjRBMS40MSAxLjQxIDAgMCAwIDE5IDI1YTEuNDIgMS40MiAwIDAgMCAxLjUtMS4yMiAxLjUzIDEuNTMgMCAwIDAgMyAwdi03LjExYTEuMTEgMS4xMSAwIDAgMCAxLjA5LTEuMThWOC42N2ExLjE4IDEuMTggMCAwIDAtMS4xOC0xLjE3Wk05LjUgMTUuNDR2NS4zOCIgY2xhc3M9ImNscy0xIi8+PC9nPjwvc3ZnPg==)}.collapsible-button .side-nav__content .toctree-checkbox:checked~label i,.collapsible-button .side-nav__content i,.scylla-icon--triangle-down,.side-nav__content .collapsible-button i,.side-nav__content .scylla-icon--expand,.side-nav__content .toctree-checkbox:checked~label .collapsible-button i,.side-nav__content .toctree-checkbox:checked~label .scylla-icon--expand{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSI1IiBmaWxsPSJub25lIj48cGF0aCBmaWxsPSIjM0EyRDU1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Im0wIDAgNSA1IDUtNUgwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.scylla-icon--university{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0ibTEuNSA4LjUgMTEtNCAxMSA0djNsLTExIDQtMTEtNHYtM3oiIGNsYXNzPSJjbHMtMSIvPjxwYXRoIGQ9Ik01LjUgMTIuNXY1YTEyLjQ2IDEyLjQ2IDAgMCAwIDcgMiAxMS4yIDExLjIgMCAwIDAgNy0ydi01IiBjbGFzcz0iY2xzLTEiLz48cGF0aCBkPSJtMTMuNSA5LjUgOCAxLjIzdjguNzdNMjIuNSAxNi41djMiIGNsYXNzPSJjbHMtMSIvPjwvZz48L3N2Zz4=)}.scylla-icon--users-blog{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTIzLjUgMi41aC0yMnYxNmgxM3Y0LjE3bDQuMDQtNC4xNyA0Ljk2LS4wNFYyLjV6IiBzdHlsZT0ic3Ryb2tlLXdpZHRoOi45OHB4O2ZpbGw6bm9uZTtzdHJva2U6Z3JheTtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQiLz48cGF0aCBkPSJNMTAuODUgOEExMC4zOCAxMC4zOCAwIDAgMSAxMSA5LjVjMCAyLjQ3LTEuMjEgNC0zIDRzLTMuNS0yLTMuNS00LjVhNC4xOCA0LjE4IDAgMCAxIDAtMSIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0iTTUuMiA1LjA3YTMuMjIgMy4yMiAwIDAgMSAyLjUtMSAzLjE2IDMuMTYgMCAwIDEgMi40IDEgNi4yMiA2LjIyIDAgMCAxIDEuMyAzLjgxLjc0Ljc0IDAgMCAwLS40MiAwYzAtLjI0IDAtLjQ0LS4wNS0uNjZoMEEzIDMgMCAwIDEgMTAgNi45di0uMjRsLS4yMS4xMkE5LjYyIDkuNjIgMCAwIDEgNC43MyA4YS4yNS4yNSAwIDAgMC0uMjIuMDljLS4xMy4xNC0uMDkuMzcgMCAuNjF2LjE4YS44NS44NSAwIDAgMC0uMzIgMEE1LjM3IDUuMzcgMCAwIDEgNS4yIDUuMDdaTTQuNTEgOC45M2MtLjM1IDAtLjU3LjA1LS42MS40NGExLjE3IDEuMTcgMCAwIDAgLjczIDEuM00xMSA4LjkzYy4zNiAwIC41Ny4wNS42Mi40NGExLjE3IDEuMTcgMCAwIDEtLjc0IDEuM002LjMxIDE0LjEzdi0uODRNOS4yNSAxMy4xOXYuOTRNMi40MiAxOGMuMTMtMS4xNS41OC0yLjUyIDEuNTgtM2ExNC43MSAxNC43MSAwIDAgMSAyLjMxLS44Mk0xMy41IDE4Yy0uMTMtMS4xNS0uNTEtMi41Mi0xLjUtM3MtMi41LTEtMi41LTEiIGNsYXNzPSJjbHMtMiIvPjxwYXRoIGQ9Ik05LjM0IDE0LjIyYTIuMjMgMi4yMyAwIDAgMS0xLjU2LjYxIDIuMzIgMi4zMiAwIDAgMS0xLjU1LS41OU0yMS41IDYuNWgtN00yMS41IDkuNWgtN00xOC41IDEyLjVoLTQiIGNsYXNzPSJjbHMtMiIvPjwvZz48L3N2Zz4=)}.admonition.caution .admonition-title:before,.admonition.warning .admonition-title:before,.scylla-icon--warning{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PG1hc2sgaWQ9ImEiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyMSIgeD0iMCIgeT0iMSIgbWFzay10eXBlPSJhbHBoYSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZmlsbD0iIzA2MTkzOCIgZD0iTTMuNSAyMmMtLjUgMC0xLS4xLTEuNS0uNEMuNiAyMC44LjEgMTguOS45IDE3LjVMOS40IDMuM2MuMy0uNC42LS44IDEtMSAuNy0uNCAxLjUtLjUgMi4zLS4zLjguMiAxLjQuNyAxLjkgMS40TDIzIDE3LjVjLjMuNS40IDEgLjQgMS41IDAgLjgtLjMgMS42LS45IDIuMS0uNS42LTEuMi45LTIgLjloLTE3Wm03LjYtMTcuNkwyLjcgMTguNWMtLjMuNS0uMSAxLjEuNCAxLjQuMS4xLjMuMS40LjFoMTYuOWMuMyAwIC41LS4xLjctLjMuMi0uMi4zLS40LjMtLjcgMC0uMiAwLS4zLS4xLS41TDEyLjkgNC40Yy0uMy0uNS0uOS0uNi0xLjQtLjQtLjIuMS0uMy4yLS40LjRaIi8+PHBhdGggZmlsbD0iIzA2MTkzOCIgZD0iTTEyIDE0Yy0uNiAwLTEtLjQtMS0xVjljMC0uNi40LTEgMS0xczEgLjQgMSAxdjRjMCAuNi0uNCAxLTEgMVpNMTIgMThjLS4zIDAtLjUtLjEtLjctLjMtLjItLjItLjMtLjQtLjMtLjcgMC0uMSAwLS4zLjEtLjQuMS0uMS4xLS4yLjItLjMuMS0uMS4yLS4yLjMtLjIuMi0uMS40LS4xLjYtLjEuMSAwIC4xIDAgLjIuMS4xIDAgLjEgMCAuMi4xIDAgMCAuMS4xLjIuMS4xLjEuMi4yLjIuMyAwIC4xLjEuMy4xLjQgMCAuMy0uMS41LS4zLjctLjMuMi0uNS4zLS44LjNaIi8+PC9tYXNrPjxnIG1hc2s9InVybCgjYSkiPjxwYXRoIGZpbGw9IiMwNjE5MzgiIGQ9Ik0wIDBoMjR2MjRIMHoiLz48L2c+PC9zdmc+)}.scylla-icon--webinars{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTEuNSA1LjVoMjJ2MTRoLTIyeiIgc3R5bGU9InN0cm9rZS1taXRlcmxpbWl0OjEwO2ZpbGw6bm9uZTtzdHJva2U6Z3JheSIvPjxwYXRoIGQ9Ik05LjQ3IDIwLjV2MS44OE0xNS41IDIwLjV2Mk02LjUgMjIuNWgxMiIgY2xhc3M9ImNscy0yIi8+PHBhdGggZD0ibTkgOSA3LjUgMy41M0w5IDE2Vjl6IiBzdHlsZT0iZmlsbDpncmF5Ii8+PC9nPjwvc3ZnPg==)}.scylla-icon--whitepapers{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMntmaWxsOm5vbmU7c3Ryb2tlOmdyYXk7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTggOWg4djJIOHoiIHN0eWxlPSJmaWxsOmdyYXkiLz48cGF0aCBkPSJNMTQuMDYgMS41IDMuNSAxLjUyVjIzLjVoMTdWN2wtNi40NC01LjV6IiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJNMTQuMzIgMS40MnYzLjM3YTIuMDYgMi4wNiAwIDAgMCAyLjA4IDIuMWgzLjY3IiBzdHlsZT0ic3Ryb2tlLW1pdGVybGltaXQ6MTA7ZmlsbDpub25lO3N0cm9rZTpncmF5Ii8+PHBhdGggZD0iTTYuNSAxOS41aDRNMTMuNSAxOS41aDRNNi41IDE2LjVoNE0xMy41IDE2LjVoNE02LjUgMTMuNWg0TTEzLjUgMTMuNWg0IiBjbGFzcz0iY2xzLTIiLz48L2c+PC9zdmc+)}.scylla-icon--workshop{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNSAyNSI+PGRlZnM+PHN0eWxlPi5jbHMtMSwuY2xzLTJ7ZmlsbDpub25lO3N0cm9rZTojNGQ0ZDRkfS5jbHMtMXtzdHJva2UtbWl0ZXJsaW1pdDoxMH0uY2xzLTJ7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kfTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJDYWxxdWVfNCIgZGF0YS1uYW1lPSJDYWxxdWUgNCI+PHBhdGggZD0iTTEuNSA1LjVoMjJ2MTRoLTIyeiIgY2xhc3M9ImNscy0xIi8+PHBhdGggZD0ibTkuNSAxOS41LS4wMyAyLjg4TTE1LjUgMTkuNXYzTTYuNSAyMi41aDEyIiBjbGFzcz0iY2xzLTIiLz48cGF0aCBkPSJtNCA4IDIgOCAuOTctMy45NUwxMSAxMiA0IDh6IiBzdHlsZT0iZmlsbDojNGQ0ZDRkIi8+PHBhdGggZD0ibTYuNDcgMTEuMzQgMy4zNyA0LjI4IiBjbGFzcz0iY2xzLTEiLz48L2c+PC9zdmc+)}.button{border:1px solid #3a2d55;border-radius:4px;display:inline;font-size:14px;letter-spacing:1px;line-height:21px;margin:0;padding:12px 14px}.button,.button:focus,.button:hover{background:transparent;color:#3a2d55}.button:focus,.button:hover{text-decoration:none}.button--reverse{background:#fff;border:0}.button--reverse:focus,.button--reverse:hover{background:#fff}.tooltip{background-color:rgba(0,0,0,.56);border-radius:4px;font-size:12px;padding:6px}.tooltip:before,.tooltip:empty{display:none!important}.has-tip{border:0;cursor:pointer}.scylla-dropdown{color:#23263b;font-size:14px;line-height:20px}.scylla-dropdown a,.scylla-dropdown a:focus,.scylla-dropdown a:hover{color:#23263b!important;padding:0!important}.scylla-dropdown__item{font-size:16px;padding:15px}.scylla-dropdown__title{align-items:center;display:flex!important;position:static!important}.scylla-dropdown__title:after{display:none!important}.scylla-dropdown__title .chevron{min-height:5px;width:10px}.scylla-dropdown__content{background:#fff;border:0;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);font-size:16px;list-style:none;margin-top:15px;overflow:hidden;padding:16px 0;width:max-content}.scylla-dropdown__content li{padding:7px 16px}.scylla-dropdown__content .contents.local>ul>li a:before,.scylla-dropdown__content .secondary-side-nav__content li a:before,.scylla-dropdown__content li .admonition-title:before,.scylla-dropdown__content li .scylla-icon,.secondary-side-nav__content .scylla-dropdown__content li a:before{margin-right:10px}.enlarge-image{cursor:zoom-in}.enlarge-image-reveal{background:transparent;border:none;cursor:zoom-out;padding:0;text-align:center;width:fit-content}.enlarge-image-reveal img{background-color:#fff;padding:15px}.header{background-color:#fff;box-shadow:0 2px 22px rgba(74,93,166,.15);justify-content:space-between;padding:12.75px 0;position:fixed;width:100%;z-index:99}.header,.header-logo{align-items:center;display:flex}.header-logo{margin-left:20px;width:auto}.header-logo__img{width:110px}.header-logo__bar{background-color:#3a2d55;border-left:1px solid #3a2d55;height:11.56px;margin:0 7.5px;width:0}.header-logo__text{color:#3a2d55;font-size:10.11px;letter-spacing:.722408px;line-height:12px;text-transform:uppercase}.header-navigation{display:none}.header-button{display:none;margin-left:15px;text-transform:uppercase}.header-search-box{display:none;margin-right:20px;width:200px}.scylla-dropdown--header .scylla-dropdown__item{font-size:14px}.scylla-dropdown--header .scylla-dropdown__title{text-transform:uppercase}.scylla-dropdown--header .scylla-dropdown__title .chevron{margin-left:10px}.contents.local>ul>li .scylla-dropdown--header .scylla-dropdown__content a:before,.scylla-dropdown--header .scylla-dropdown__content .admonition-title:before,.scylla-dropdown--header .scylla-dropdown__content .contents.local>ul>li a:before,.scylla-dropdown--header .scylla-dropdown__content .scylla-icon,.scylla-dropdown--header .scylla-dropdown__content .secondary-side-nav__content li a:before,.secondary-side-nav__content li .scylla-dropdown--header .scylla-dropdown__content a:before{min-height:20px;width:20px}@media screen and (min-width:1024px){.header{padding:18px 0}.header-logo__img{width:152px}.header-logo__bar{height:16px;margin:0 10px}.header-logo__text{font-size:14px;letter-spacing:.722408px;line-height:12px;text-transform:uppercase}.header-navigation{align-items:center;display:flex;justify-content:center}.header-search-box{display:block}}@media screen and (min-width:1200px){.header-logo{margin-left:30px;width:357px}.header-search-box{margin-right:30px;max-width:20%;width:318px}.header-button{display:block}}.side-nav{background:#fff;display:none;height:100vh;left:0;line-height:24px;max-height:calc(100vh - 50px);overflow-y:auto;padding:20px 20px 0;position:fixed;top:50px;width:100%;z-index:100}.side-nav__title{font-weight:700;margin-bottom:20px}.side-nav__content{max-width:90%;overflow-wrap:break-word}.side-nav__content label,.side-nav__content label i{margin:0;padding:0}.side-nav__content label{font-size:inherit;line-height:1;margin-left:5px;max-height:5px}.collapsible-button .side-nav__content i,.side-nav__content .collapsible-button i,.side-nav__content .scylla-icon--expand{height:5px;vertical-align:top;width:10px}.side-nav__content .toctree-checkbox{display:none;position:absolute;right:20px}.side-nav__content .toctree-checkbox~ul{display:none;margin-right:20px}.side-nav__content .toctree-checkbox:checked~ul{display:block}.side-nav__content ul{margin:0}.side-nav__content a{color:#23263b}.side-nav__content a:hover{color:#3c4fe0;font-weight:400}.side-nav__content li{list-style:none;padding:0 0 24px}.side-nav__content li.has-children{align-items:center;display:flex;flex-wrap:wrap}.side-nav__content li.has-children>a{max-width:calc(100% - 15px)}.side-nav__content li.has-children.current{padding-bottom:20px}.side-nav__content li.has-children:hover>a{color:#3c4fe0}.side-nav__content li.has-children:hover>.toctree-checkbox~label i{filter:invert(38%) sepia(71%) saturate(6789%) hue-rotate(231deg) brightness(90%) contrast(95%)}.side-nav__content li.current-page>a{color:#3c4fe0}.side-nav__content li.current-page>.toctree-checkbox:checked~label i{filter:invert(38%) sepia(71%) saturate(6789%) hue-rotate(231deg) brightness(90%) contrast(95%)}.side-nav__content li ul{margin-top:18px;width:100%}.side-nav__content li ul li{border-left:1px solid #3c4fe0;padding:4px 0 4px 13px}.side-nav__content li ul ul{margin-left:0}.side-nav__content li .label{display:none}.side-nav__versions{max-width:90%}.side-nav__search,.side-nav__versions .dropdown{margin-bottom:20px}.collapsible-button{background:#fff;background-color:#fff;border:0;border-radius:8px;border-radius:50%;bottom:10px;box-shadow:0 4px 25px rgba(0,0,0,.15);cursor:pointer;display:none;font-size:0;left:300px;overflow:hidden;padding:13.5px;position:fixed}.collapsible-button i{height:16px;margin:0;width:16px}.side-nav--collapsed .collapsible-button{border-radius:0 20px 20px 0;left:-10px}.side-nav--collapsed .collapsible-button i{transform:rotate(180deg)}.layout--has-banner .side-nav{max-height:calc(100vh - 92.5px)}@media screen and (min-width:1024px){.side-nav{background-color:#f6f8ff;display:block;height:100%;left:auto;max-height:100vh;max-height:calc(100vh - 80px);padding:30px 40px;top:80px;width:286px;z-index:25}.side-nav__content{max-width:100%;padding-bottom:180px}.side-nav__search{display:none}.side-nav__versions{max-width:100%}.toctree-checkbox{right:40px}.layout--has-banner .side-nav{max-height:calc(100vh - 150px)}}@media screen and (min-width:1200px){.side-nav{width:357px}.side-nav--collapsed{background-color:transparent;padding-left:0;padding-right:0;width:126px}.side-nav--collapsed .side-nav-content{display:none}.collapsible-button{display:block}}.side-nav-toggle{cursor:pointer;display:block;margin-right:20px;position:relative;z-index:300}@media screen and (min-width:1024px){.side-nav-toggle{display:none}}.secondary-side-nav{display:none;height:100%;line-height:24px;padding:20px;width:100%}.secondary-side-nav__content{overflow-wrap:break-word}.secondary-side-nav__content ul{list-style:none;margin:0}.secondary-side-nav__content li{border-bottom:1px solid rgba(90,94,154,.1);display:none;padding:10px 0;word-break:break-word}.secondary-side-nav__content li:last-child{border:0}.secondary-side-nav__content li .label{display:none}.secondary-side-nav__content li a{align-items:baseline;color:#b3bac5;display:flex;font-size:14px}.secondary-side-nav__content li a:before{content:"";filter:invert(40%) sepia(11%) saturate(2157%) hue-rotate(198deg) brightness(89%) contrast(87%)!important;flex-shrink:0;margin-right:10px;min-height:10px;opacity:.5;width:6px}.secondary-side-nav__content li a.current,.secondary-side-nav__content li a:hover{color:#23263b;font-weight:400}.secondary-side-nav__content li a.current:before,.secondary-side-nav__content li a:hover:before{filter:brightness(0);opacity:1}.secondary-side-nav__content li a.current{font-weight:700}.secondary-side-nav__content>ul>li>ul>li{display:block}.secondary-side-nav__content>ul>li{border:0;display:block}.secondary-side-nav__content>ul>li>a{display:none}@media screen and (min-width:1200px){.secondary-side-nav{display:block;max-height:100vh;max-height:calc(100vh - 80px);overflow-y:auto;padding:60px 60px 60px 20px;position:fixed;top:80px;width:286px}.secondary-side-nav__content{padding-bottom:180px}.layout--has-banner .secondary-side-nav{max-height:calc(100vh - 150px)}}.layout{display:flex}.pre-content{align-items:center;display:flex;justify-content:space-between;margin-bottom:20px}.content{margin-top:50px;max-width:1440px;overflow-wrap:break-word;padding:20px;width:100%}.content .line-block,.content p{line-height:28px;margin-bottom:20px}.content ul{list-style:none}.content ul li:before{color:#b3bac5;content:"•";float:left;font-family:FontAwesome;font-size:20px;font-weight:700;margin-left:-1em;margin-top:-2px;width:1em}.content ul ul{list-style:circle}.content ul ul li:before{content:""}.content ol ol{list-style:lower-latin}.content img{margin-bottom:30px}.content .inline-icon.fa-check{color:#42c4e6}.layout--full-width .content{max-width:100%;padding:0;width:100%}.layout--full-width .content .hero-wrapper,.layout--full-width .content .topics-grid{max-width:1190px}.layout--full-width .content.content--collapsed,.layout--full-width:not(.layout--sidebar) .content{margin-left:0}.landing__content{padding:0 16px}@media screen and (min-width:1024px){.content{margin-left:286px;margin-top:80px;min-height:calc(100vh - 260px);padding-bottom:100px;width:calc(100% - 286px)}}@media screen and (min-width:1200px){.content{margin-left:357px;padding:60px 40px 40px;width:calc(100% - 643px)}.content--collapsed{margin-left:126px;width:calc(100% - 412px)}.pre-content{margin-bottom:10px}.landing__content{padding:0 60px}.landing--floating .landing__content{position:relative;top:-70px}}.contents.local>ul{margin-bottom:30px;margin-left:0}.contents.local>ul>li{border-bottom:1px solid rgba(90,94,154,.1);padding:10px 0;word-break:break-word}.contents.local>ul>li:before{content:""}.contents.local>ul>li:last-child{border:0}.contents.local>ul>li ul{display:none}.contents.local>ul>li p{margin:0}.contents.local>ul>li a{font-size:14px}.contents.local>ul>li a:before{content:"";filter:invert(40%) sepia(11%) saturate(2157%) hue-rotate(198deg) brightness(89%) contrast(87%)!important;margin-right:10px;min-height:10px;opacity:.5;width:10px}.contents.local>ul>li a.current:before,.contents.local>ul>li a:hover:before{filter:brightness(0);opacity:1}.topic-title{color:rgba(35,38,59,.75);font-size:10px;letter-spacing:1.5px;margin-bottom:0;text-transform:uppercase}.notice{margin-top:40px}.footer{background-color:#fff;box-shadow:0 -4px 10px hsla(0,0%,82%,.25);padding:30px 0;position:relative;width:100%;z-index:50}.footer-group{margin:0 auto;max-width:1030px;padding:0 20px}.footer-top{align-items:center;border-bottom:1px solid rgba(0,0,0,.1);display:flex;flex-wrap:wrap;justify-content:space-between;padding-bottom:8px;text-align:center}.footer-logo{margin-bottom:30px;width:100%}.footer-logo img{float:left;height:36px}.footer-links{text-align:left}.footer-links__link{color:#333;font-size:12px;font-weight:500;letter-spacing:2.4px;margin-right:16px;text-transform:uppercase}.footer-actions{align-items:center;display:flex;justify-content:space-between;width:90px}.footer-actions__link{color:#000}.footer-actions__link img{height:23px}.footer-bottom{color:#979797;display:flex;flex-wrap:wrap;font-size:12px;font-style:normal;font-weight:400;justify-content:center;letter-spacing:1.4px;line-height:23px;padding:20px 0 10px;text-align:center;text-transform:uppercase}@media screen and (max-width:510px){.footer-links{margin-bottom:20px}}@media screen and (min-width:1024px){.footer{padding:30px 0}.footer-group{padding:0}.footer-top{padding-bottom:30px}.footer-logo{margin:0;width:auto}.footer-links{padding:0 40px}.footer-links__link{font-size:14px;margin-right:28px}.footer-actions{width:110px}.footer-actions__link img{height:28px}.footer-bottom .footer-bottom__copyright,.footer-bottom .footer-bottom__last-updated,.footer-bottom .footer-bottom__version{padding:0 10px}.footer-bottom .footer-bottom__copyright{border-left:none}}.not-found{background-color:#f6f8ff;height:100%;overflow:hidden}.not-found__icon{display:block;margin:40px auto;max-width:300px}.not-found__text{text-align:center}.not-found__text h1{font-size:60px;line-height:1}.not-found__text p{margin:30px 0;width:100%}.not-found__button{text-transform:uppercase}.admonition{border-radius:4px;box-shadow:0 4px 4px rgba(0,0,0,.12);color:rgba(0,0,0,.56);font-size:14px;line-height:20px;margin-bottom:30px;overflow:auto;padding:20px 20px 20px 52px;position:relative}.admonition:before{bottom:0;content:" ";left:0;position:absolute;right:0;top:0;z-index:-1}.admonition-title{color:#23263b;left:-32px;position:relative}.admonition-title:before{content:"";margin-right:8px;min-height:24px;width:24px}.admonition p{margin-bottom:0!important}.admonition.tip{border:1px solid #43a047}.admonition.tip:before{border-left:8px solid rgba(67,160,71,.4)}.admonition.tip .admonition-title:before{filter:invert(47%) sepia(11%) saturate(2286%) hue-rotate(73deg) brightness(109%) contrast(88%)}.admonition.note{border:1px solid #1976d2}.admonition.note:before{border-left:8px solid rgba(25,118,210,.4)}.admonition.note .admonition-title:before{filter:invert(44%) sepia(55%) saturate(2310%) hue-rotate(191deg) brightness(81%) contrast(103%)}.admonition.caution{border:1px solid #ffab00}.admonition.caution:before{border-left:8px solid rgba(255,171,0,.4)}.admonition.caution .admonition-title:before{filter:invert(77%) sepia(56%) saturate(3332%) hue-rotate(357deg) brightness(98%) contrast(108%)}.admonition.warning{border:1px solid #e74c3c}.admonition.warning:before{border-left:8px solid rgba(231,76,60,.4)}.admonition.warning .admonition-title:before{filter:invert(41%) sepia(42%) saturate(6427%) hue-rotate(343deg) brightness(99%) contrast(83%)}.breadcrumbs{margin-bottom:0;text-transform:uppercase}.breadcrumbs .bread__item,.breadcrumbs .bread__item:not(.bread__item--last):after,.breadcrumbs a{color:#23263b;font-size:12px;font-weight:400;letter-spacing:1.5px;line-height:2;margin:0;padding:0}.breadcrumbs .bread__item:before{display:none}.breadcrumbs .bread__item:not(.bread__item--last):after{content:"/";margin:0 5px;opacity:1;position:relative}.breadcrumbs .bread__highlight{color:#3c4fe0}.breadcrumbs .bread__highlight:hover{font-weight:700;text-decoration:none}code{background-color:#f7f8f9;border:none;border-radius:4px;color:#23263b;font-size:14px}code.download{background:none;color:#23263b}.highlight{background:transparent!important}.highlight pre{background-color:#f7f8f9;border-radius:8px;color:#23263b;font-size:14px;line-height:26px;margin-bottom:30px;overflow:auto;padding:16px}.highlight a.copybtn{right:1em;top:1em}.highlighttable{background-color:#f7f8f9;border-radius:16px;box-shadow:none}.highlighttable tbody{background-color:transparent;border:0}.highlighttable tbody td{padding:15px!important}.highlighttable tbody tr{border-top:none}.highlighttable .linenos{background-color:#f7f8f9;color:#5a7184;width:50px}.highlighttable .linenos span{line-height:26px}.highlighttable .highlight pre{background-color:transparent;margin:0;padding:0}.highlighttable .highlight a.copybtn{right:.2em;top:.2em}.hide-copy-button .copybtn{display:none}.sphinx_collapse__label{display:flex!important;flex-direction:row-reverse;font-size:medium;font-weight:700;justify-content:flex-end;margin-left:0!important}.sphinx_collapse__icon{margin-left:5px;margin-right:0}.sphinx_collapse__input:checked~.sphinx_collapse__label,.sphinx_collapse__label:hover{color:#3c4fe0}.sphinx_collapse__input:checked~.sphinx_collapse__label .sphinx_collapse__icon,.sphinx_collapse__label:hover .sphinx_collapse__icon{border-top-color:#3c4fe0}.sphinx_collapse__content{margin-top:10px}.contribute{margin:0 0 20px}.contribute__item{font-size:14px;list-style:none;padding-bottom:10px}.contribute__item .icon{margin-right:5px}.content-navigation{display:flex;justify-content:space-between;margin-top:40px}.navigation{max-width:50%;word-break:break-word}.navigation,.navigation__link{display:flex}.navigation__title{word-wrap:break-word;color:#23263b;font-size:12px;font-weight:500;letter-spacing:1.5px;line-height:24px;text-transform:uppercase}.navigation__title .colored{color:#42c4e6}.navigation__button{background:#fff;background-color:#fff;border:0;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);cursor:pointer;display:none;font-size:0;height:fit-content;overflow:hidden;padding:13.5px 16.5px}.navigation__button i{height:16px;margin:0;width:10px}.navigation--prev .navigation__title{margin-left:15px}.navigation--next .navigation__title{margin-right:15px;text-align:right}@media screen and (min-width:1200px){.navigation__title{display:inline-block}.navigation__button{display:block}.navigation--next .navigation__title{text-align:left}}.scylla-dropdown--versions .scylla-dropdown__item{background:#fff;border-radius:8px;box-shadow:0 28px 32px rgba(0,0,0,.06);width:100%}.scylla-dropdown--versions .scylla-dropdown__title{align-items:center;display:flex;justify-content:space-between}.scylla-dropdown--versions .scylla-dropdown__title .chevron{min-height:12px;transform:rotate(90deg);width:8px}@media screen and (min-width:1024px){.scylla-dropdown--versions .scylla-dropdown__item{box-shadow:none}}.feedback-container{font-size:16px;margin-top:40px;text-align:left}.feedback-container__title{font-weight:700;margin-bottom:5px!important}.feedback-container__button{background:#fff;border:0;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);cursor:pointer;margin:4px;overflow:hidden;padding:8px}.feedback-container__button.active{border:1px solid #3c4fe0}.feedback-container__icon{height:20px;width:20px}.feedback-container__message{font-size:16px;margin-top:10px}.hero{background:#f6f8ff;margin-bottom:30px;overflow:hidden;padding:30px 16px;text-align:left}.hero__title{font-size:28px;font-weight:500;line-height:38px;margin-bottom:14px;max-width:229px}.hero__text{font-size:16px;line-height:26px;max-width:343px}.hero__text a{border-bottom:1px dotted #23263b;color:#23263b}.hero__text p{margin-bottom:0!important}.hero__img{position:absolute;right:-18px;top:20px}.hero__img img{margin-bottom:0!important;width:124px}.hero__button{margin-top:20px;text-transform:uppercase}.hero__button .icon{margin-right:5px}.hero__search-box{box-shadow:0 4px 25px rgba(0,0,0,.02);margin-top:20px}.hero-wrapper{align-items:center;display:flex;justify-content:space-between;margin:0 auto;position:relative}@media screen and (min-width:640px){.hero{padding:60px 16px}.hero__title{font-size:32px;line-height:42px;max-width:482px}.hero__text{font-size:18px;line-height:26px;max-width:482px}.hero__img{display:block;position:static}.hero__img img{height:100%;width:295px}.hero .hero-wrapper{flex-direction:row-reverse}.hero .landing--floating .hero{padding:30px 16px 100px}}@media screen and (min-width:1024px){.hero{padding:60px}}.label{background-color:#23263b;border:0;border-radius:4px;color:#fff;font-size:inherit}.label--note{background-color:#1976d2}.label--tip{background-color:#43a047}.label--caution{background-color:#ffab00}.label--warning{background-color:#e74c3c}.last-updated{color:#4458a3;font-size:12px;letter-spacing:1.5px;margin:10px 0;text-transform:uppercase}.last-updated__icon{font-size:14px}@media screen and (min-width:1024px){.last-updated{float:right;margin:0}}.panel{border:0;border-radius:4px;margin-bottom:30px}.promo-banner{background-color:#4458a3;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDQwIiBoZWlnaHQ9IjcwIiBmaWxsPSJub25lIj48bWFzayBpZD0iYSIgd2lkdGg9IjE0NDAiIGhlaWdodD0iNzAiIHg9IjAiIHk9IjAiIG1hc2stdHlwZT0iYWxwaGEiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiPjxwYXRoIGZpbGw9IiM0NDU4QTMiIGQ9Ik0wIDBoMTQ0MHY3MEgweiIvPjwvbWFzaz48ZyBmaWxsPSIjNTA2NEFFIiBtYXNrPSJ1cmwoI2EpIj48cGF0aCBkPSJNLTE5MyAyMDEuODg0IDEuNS0xMzUgMzU3LjQzNiA3MC41bC0xOTQuNSAzMzYuODg0ek0xMDkyLjkyLTM4LjAwOSA5NzIuODAzLTI0Ni4wNTcgNDAyLjk5NiA4Mi45MiA1MjMuMTEzIDI5MC45N3oiLz48cGF0aCBkPSJtMTAzOC0zOC4wMDkgMTIwLjExNy0yMDguMDQ5IDU2OS44MDcgMzI4Ljk3OS0xMjAuMTE3IDIwOC4wNDl6Ii8+PC9nPjwvc3ZnPg==);background-position:50%;background-repeat:no-repeat;background-size:cover;display:none;overflow:hidden;position:fixed;top:0;width:100%;z-index:900}.promo-banner__icon{margin-right:15px}.promo-banner__icon img{height:40px}.promo-banner__title{color:#fff;font-size:12px;line-height:16px;margin-right:15px}.promo-banner__button{background:#fff;border-radius:4px;font-size:12px;min-width:max-content;padding:5px}.promo-banner__close{display:none;position:absolute;right:16px;top:16px}.contents.local>ul>li .promo-banner__close a:before,.promo-banner__close .admonition-title:before,.promo-banner__close .contents.local>ul>li a:before,.promo-banner__close .scylla-icon,.promo-banner__close .secondary-side-nav__content li a:before,.secondary-side-nav__content li .promo-banner__close a:before{filter:brightness(100%);height:34px;width:34px}.promo-banner__close:hover{cursor:pointer;filter:opacity(.8)}.promo-banner-wrapper{align-items:center;display:flex;justify-content:center;padding:5.85px 20px}@media(min-width:1024px){.promo-banner__title{font-size:18px;line-height:23px}.promo-banner__button{font-size:14px;padding:8.5px}.promo-banner__close{display:block}.promo-banner-wrapper{flex-direction:unset;padding:16px}}.custom-scroll-bar::-webkit-scrollbar{background-color:transparent;width:5px}.custom-scroll-bar::-webkit-scrollbar-thumb{background-color:#b3bac5;-webkit-border-radius:8px;border-radius:8px}.search-box{background:#f7f8f9;border-radius:4px;display:flex;padding:10px 15px}.search-box--hero{background-color:#fff;padding:12px 14px}.search-box:before{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTEwLjUgMThhNy41IDcuNSAwIDEgMCAwLTE1IDcuNSA3LjUgMCAwIDAgMCAxNVpNMjEgMjFsLTUuMi01LjIiLz48L3N2Zz4=);background-repeat:no-repeat;background-size:contain;content:"";display:inline-block;filter:brightness(0);margin-top:2px;min-height:18px;min-width:18px;vertical-align:middle;width:20px}.search-box .er-dummy-search,.search-box .er-dummy-search-box,.search-box .er-search-form,.search-box ci-search,.search-box input{margin:0!important;width:100%!important}.search-box input{background:transparent!important;color:rgba(80,80,80,.5)!important;font-size:14px!important;padding:0!important}.search-box input::placeholder{color:rgba(80,80,80,.5)!important;opacity:1!important}.search-box button{display:none!important}.er_search_suggestions{background:#fff;border:0;border:0!important;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);overflow:hidden}.er_search_suggestions .er-search-result-box{border-width:1px!important;padding-bottom:10px!important;padding-top:10px!important}.er_search_suggestions .er-search-result-box:hover{background:#f7f8f9!important}.er_search_suggestions .er_more_result_btn{cursor:pointer}.er_search_suggestions h3{font-size:16px!important}.er-search-content{padding:20px!important}#er_search_results .er-search-result-box{display:block!important;margin:10px auto 0!important;width:100%!important}#er_search_results .text,#er_search_results .title a,#er_search_results .url a{max-width:100%!important}#search-result-input-form{max-width:800px!important}#er_search_button{text-align:center}#er_clear_input{right:0!important;top:0!important}.er-facet-header{background-color:transparent!important;border:0!important;padding:0 0 8px!important}.er-facet-val{padding:5px 2px!important}.er-facet-val input{display:block!important;margin:0}#er_search_pagination{margin-top:20px!important}#er_search_pagination li.er-paginator-list.er-active{border-bottom:0!important;font-weight:700}.er-suggestion-sm .er_search_input_dummy{margin:0!important}.er-suggestion-sm .er_search_button_dummy{border:0!important}#er_gcs_mobile_model_container .er-facet-values .er-facet-val{align-items:baseline}@media screen and (min-width:640px){.er-facets{display:none;max-width:300px!important;min-width:auto!important;width:auto!important}}@media screen and (min-width:1024px){.er-suggestions{left:15px!important}}@media screen and (min-width:1200px){.er-facets{display:block;position:fixed!important}.er-facet-count{display:none}}.sphinx-tabs{margin-bottom:30px}.sphinx-tabs-tab{border-bottom:1px solid rgba(0,0,0,.56);color:rgba(0,0,0,.56);cursor:pointer;font-size:14px;font-weight:500;line-height:13px;padding:20px 25px}.sphinx-tabs-tab[aria-selected=true]{border-bottom:2px solid #2196f3;color:#2196f3;padding-bottom:19px}.sphinx-tabs-panel{margin:30px 0}.table-wrapper{border:1px solid #e0e0e0;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.25);display:block;margin-bottom:30px;max-width:100%;overflow-x:auto}table{color:#000;font-size:14px;line-height:24px;margin:0;overflow:hidden}table p{margin:0!important}table caption{background:#f6f8ff;border-bottom:1px solid #e0e0e0;color:#23263b;padding:10px 25px}table thead{background:#f6f8ff;border:0;border-bottom:1px solid #4458a3}table thead th{color:#23263b;font-size:14px;font-weight:700}table td,table thead th{padding:20px 25px}table tbody tr{background-color:transparent!important;border-top:1px solid #e0e0e0;line-height:18px}table:not(.highlighttable) tbody tr:first-child{border-top:1px solid #4458a3}table.thead-border thead .row-odd th{color:#23263b}table.thead-border thead .row-even th{font-weight:400}table.thead-border thead th{border:1px solid #e0e0e0}table.thead-border thead tr:first-child th{border-top:none}table.thead-border thead tr:last-child th{border-bottom:none}table.thead-border thead tr th:first-child{border-left:none}table.thead-border thead tr th:last-child{border-right:none}.topics-grid{display:block;margin:0 auto 30px}.topics-grid__title{color:#23263b;font-size:24px;font-weight:700;line-height:32px;margin-bottom:6px}.topics-grid__text{color:#4458a3;font-size:18px;line-height:24px}.topics-grid--scrollable .hs{-ms-overflow-style:none;display:grid;grid-auto-flow:column;overflow-x:scroll;padding:20px 10px;scrollbar-width:none}.topics-grid--scrollable .hs::-webkit-scrollbar{display:none}.topics-grid--scrollable .hs .topic-box:last-child:after{content:"";width:20px}.topic-box{align-items:stretch;display:flex}.topic-box .card{background:#fff;border:1px solid transparent;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);display:flex;flex-direction:column;font-size:18px;margin:0 auto 30px;overflow:hidden;padding:20px;position:relative}.topic-box .card:hover{border:1px solid #4458a3;color:#23263b;font-weight:400}.topic-box__title{color:#23263b;font-size:16px;font-weight:700;line-height:24px;margin-bottom:0}.topic-box__title img{bottom:0;opacity:.3;position:absolute;right:0;top:0}.topic-box__body{color:#000;display:flex;flex-direction:column;flex-grow:1;max-width:80%}.topic-box__body .container{flex-grow:1;margin:0;padding:0}.topic-box__body .line-block,.topic-box__body p{font-size:16px;line-height:19px;margin-top:10px}.topic-box__anchor{color:#42c4e6;font-size:14px;font-weight:700;line-height:24px}.topic-box__icon{display:block;font-size:50px;margin-bottom:20px}.topic-box__icon i{filter:brightness(0);min-height:50px;width:100%}.topic-box__icon img{bottom:-12px;display:none;height:140px;margin:0;opacity:.3;position:absolute;right:-5px}.topic-box--product .card{box-shadow:none;padding:20px;text-align:center}.topic-box--product .card .topic-box__title{color:#23263b;font-size:14px}.topic-box--product .card .topic-box__body{display:flex;flex-direction:column;max-width:100%}.topic-box--product .card .topic-box__body .line-block,.topic-box--product .card .topic-box__body p{font-size:12px}.topic-box--product .card .topic-box__icon img{display:inline-block;max-height:84px;opacity:1;position:static}.topic-box--product .card:hover{background:#fff;border:0;border-radius:8px;box-shadow:0 4px 25px rgba(0,0,0,.15);overflow:hidden}@media screen and (max-width:1024px){.topics-grid--scrollable .topic-box{width:280px!important}.topic-box--product:nth-last-child(-n+2) .card{margin-bottom:0}}@media screen and (min-width:1024px){.topics-grid{margin-bottom:10px}.topics-grid__text{font-size:16px}.topics-grid--scrollable .hs{display:flex;overflow-x:initial;padding:0}.topics-grid--scrollable .hs .topic-box:last-child:after{display:none}.topic-box .card{margin-bottom:60px;padding:45px 30px}.topic-box__title{font-size:20px;line-height:32px}.topic-box__body .line-block,.topic-box__body p{font-size:18px;line-height:26px}.topic-box__anchor{font-size:20px;line-height:26px}.topic-box .topic-box__icon img{display:inline-block}.topic-box--product .card{padding:20px}.topic-box--product .card .topic-box__title{font-size:18px;line-height:24px}.topic-box--product .card .topic-box__body .line-block,.topic-box--product .card .topic-box__body p{font-size:14px}.topic-box--product .card .topic-box__icon img{max-height:111px}.landing .topics-grid--products{margin-bottom:40px}} \ No newline at end of file diff --git a/stable/_static/doctools.js b/stable/_static/doctools.js new file mode 100644 index 00000000..d06a71d7 --- /dev/null +++ b/stable/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/stable/_static/documentation_options.js b/stable/_static/documentation_options.js new file mode 100644 index 00000000..7e4c114f --- /dev/null +++ b/stable/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/stable/_static/file.png b/stable/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/stable/_static/file.png differ diff --git a/stable/_static/img/banner-background.svg b/stable/_static/img/banner-background.svg new file mode 100644 index 00000000..f8520d5b --- /dev/null +++ b/stable/_static/img/banner-background.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/stable/_static/img/favicon-228x228.png b/stable/_static/img/favicon-228x228.png new file mode 100644 index 00000000..f30770c7 Binary files /dev/null and b/stable/_static/img/favicon-228x228.png differ diff --git a/stable/_static/img/favicon-32x32.png b/stable/_static/img/favicon-32x32.png new file mode 100644 index 00000000..aae1708f Binary files /dev/null and b/stable/_static/img/favicon-32x32.png differ diff --git a/stable/_static/img/favicon.ico b/stable/_static/img/favicon.ico new file mode 100644 index 00000000..6c7484f0 Binary files /dev/null and b/stable/_static/img/favicon.ico differ diff --git a/stable/_static/img/icons/icon-about-team.svg b/stable/_static/img/icons/icon-about-team.svg new file mode 100644 index 00000000..5448c7f0 --- /dev/null +++ b/stable/_static/img/icons/icon-about-team.svg @@ -0,0 +1 @@ +icon-about-team diff --git a/stable/_static/img/icons/icon-about-us-m.svg b/stable/_static/img/icons/icon-about-us-m.svg new file mode 100644 index 00000000..09107d95 --- /dev/null +++ b/stable/_static/img/icons/icon-about-us-m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/icons/icon-about-us.svg b/stable/_static/img/icons/icon-about-us.svg new file mode 100644 index 00000000..1b1fcc83 --- /dev/null +++ b/stable/_static/img/icons/icon-about-us.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/icons/icon-alternator.svg b/stable/_static/img/icons/icon-alternator.svg new file mode 100644 index 00000000..7c2b4eba --- /dev/null +++ b/stable/_static/img/icons/icon-alternator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/icons/icon-apps.svg b/stable/_static/img/icons/icon-apps.svg new file mode 100644 index 00000000..7e936120 --- /dev/null +++ b/stable/_static/img/icons/icon-apps.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-architecture.svg b/stable/_static/img/icons/icon-architecture.svg new file mode 100644 index 00000000..67ebbc2f --- /dev/null +++ b/stable/_static/img/icons/icon-architecture.svg @@ -0,0 +1 @@ +icon-architecture diff --git a/stable/_static/img/icons/icon-benchmarks.svg b/stable/_static/img/icons/icon-benchmarks.svg new file mode 100644 index 00000000..e1ce2c1d --- /dev/null +++ b/stable/_static/img/icons/icon-benchmarks.svg @@ -0,0 +1 @@ +icon-benchmarks diff --git a/stable/_static/img/icons/icon-blog.svg b/stable/_static/img/icons/icon-blog.svg new file mode 100644 index 00000000..f4096cbf --- /dev/null +++ b/stable/_static/img/icons/icon-blog.svg @@ -0,0 +1 @@ +icon-blog2 diff --git a/stable/_static/img/icons/icon-careers.svg b/stable/_static/img/icons/icon-careers.svg new file mode 100644 index 00000000..2a7c6ea0 --- /dev/null +++ b/stable/_static/img/icons/icon-careers.svg @@ -0,0 +1 @@ +icon-careers diff --git a/stable/_static/img/icons/icon-chevron-left.svg b/stable/_static/img/icons/icon-chevron-left.svg new file mode 100644 index 00000000..3afa25c4 --- /dev/null +++ b/stable/_static/img/icons/icon-chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/stable/_static/img/icons/icon-chevron-right.svg b/stable/_static/img/icons/icon-chevron-right.svg new file mode 100644 index 00000000..44eb829c --- /dev/null +++ b/stable/_static/img/icons/icon-chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/stable/_static/img/icons/icon-circe.svg b/stable/_static/img/icons/icon-circe.svg new file mode 100644 index 00000000..875e4216 --- /dev/null +++ b/stable/_static/img/icons/icon-circe.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-clock.svg b/stable/_static/img/icons/icon-clock.svg new file mode 100644 index 00000000..8c924698 --- /dev/null +++ b/stable/_static/img/icons/icon-clock.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-close.svg b/stable/_static/img/icons/icon-close.svg new file mode 100644 index 00000000..d1162b73 --- /dev/null +++ b/stable/_static/img/icons/icon-close.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/stable/_static/img/icons/icon-cloud-docs.svg b/stable/_static/img/icons/icon-cloud-docs.svg new file mode 100644 index 00000000..a9069bb6 --- /dev/null +++ b/stable/_static/img/icons/icon-cloud-docs.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-cloud.svg b/stable/_static/img/icons/icon-cloud.svg new file mode 100644 index 00000000..cfb2318d --- /dev/null +++ b/stable/_static/img/icons/icon-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/icons/icon-comparison.svg b/stable/_static/img/icons/icon-comparison.svg new file mode 100644 index 00000000..49d809a5 --- /dev/null +++ b/stable/_static/img/icons/icon-comparison.svg @@ -0,0 +1 @@ +icon-comparison diff --git a/stable/_static/img/icons/icon-contact-us.svg b/stable/_static/img/icons/icon-contact-us.svg new file mode 100644 index 00000000..9df3145d --- /dev/null +++ b/stable/_static/img/icons/icon-contact-us.svg @@ -0,0 +1 @@ +icon-contact-us diff --git a/stable/_static/img/icons/icon-developers-blog.svg b/stable/_static/img/icons/icon-developers-blog.svg new file mode 100644 index 00000000..ee804197 --- /dev/null +++ b/stable/_static/img/icons/icon-developers-blog.svg @@ -0,0 +1 @@ +icon-developers-blog diff --git a/stable/_static/img/icons/icon-docs.svg b/stable/_static/img/icons/icon-docs.svg new file mode 100644 index 00000000..5501492f --- /dev/null +++ b/stable/_static/img/icons/icon-docs.svg @@ -0,0 +1 @@ +icon-docs diff --git a/stable/_static/img/icons/icon-enterprise-m.svg b/stable/_static/img/icons/icon-enterprise-m.svg new file mode 100644 index 00000000..97be900b --- /dev/null +++ b/stable/_static/img/icons/icon-enterprise-m.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/_static/img/icons/icon-enterprise.svg b/stable/_static/img/icons/icon-enterprise.svg new file mode 100644 index 00000000..ee1ac262 --- /dev/null +++ b/stable/_static/img/icons/icon-enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/icons/icon-events.svg b/stable/_static/img/icons/icon-events.svg new file mode 100644 index 00000000..ba5f2118 --- /dev/null +++ b/stable/_static/img/icons/icon-events.svg @@ -0,0 +1 @@ +icon-events diff --git a/stable/_static/img/icons/icon-exclamation.svg b/stable/_static/img/icons/icon-exclamation.svg new file mode 100644 index 00000000..a7eb4b77 --- /dev/null +++ b/stable/_static/img/icons/icon-exclamation.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/stable/_static/img/icons/icon-expand.svg b/stable/_static/img/icons/icon-expand.svg new file mode 100644 index 00000000..38065653 --- /dev/null +++ b/stable/_static/img/icons/icon-expand.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/stable/_static/img/icons/icon-forum.svg b/stable/_static/img/icons/icon-forum.svg new file mode 100644 index 00000000..37a709f7 --- /dev/null +++ b/stable/_static/img/icons/icon-forum.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-getting-started.svg b/stable/_static/img/icons/icon-getting-started.svg new file mode 100644 index 00000000..702500be --- /dev/null +++ b/stable/_static/img/icons/icon-getting-started.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-glossary.svg b/stable/_static/img/icons/icon-glossary.svg new file mode 100644 index 00000000..e8329c2a --- /dev/null +++ b/stable/_static/img/icons/icon-glossary.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-home.svg b/stable/_static/img/icons/icon-home.svg new file mode 100644 index 00000000..f0b9c254 --- /dev/null +++ b/stable/_static/img/icons/icon-home.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-infoworld.svg b/stable/_static/img/icons/icon-infoworld.svg new file mode 100644 index 00000000..906e8727 --- /dev/null +++ b/stable/_static/img/icons/icon-infoworld.svg @@ -0,0 +1 @@ +icon-infoworld diff --git a/stable/_static/img/icons/icon-integrations.svg b/stable/_static/img/icons/icon-integrations.svg new file mode 100644 index 00000000..1ef0920d --- /dev/null +++ b/stable/_static/img/icons/icon-integrations.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-knowledge-base.svg b/stable/_static/img/icons/icon-knowledge-base.svg new file mode 100644 index 00000000..88445127 --- /dev/null +++ b/stable/_static/img/icons/icon-knowledge-base.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-less.svg b/stable/_static/img/icons/icon-less.svg new file mode 100644 index 00000000..3094127d --- /dev/null +++ b/stable/_static/img/icons/icon-less.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/stable/_static/img/icons/icon-live-test.svg b/stable/_static/img/icons/icon-live-test.svg new file mode 100644 index 00000000..dcb5916c --- /dev/null +++ b/stable/_static/img/icons/icon-live-test.svg @@ -0,0 +1 @@ +icon-live-test diff --git a/stable/_static/img/icons/icon-mail-list.svg b/stable/_static/img/icons/icon-mail-list.svg new file mode 100644 index 00000000..0e6192a3 --- /dev/null +++ b/stable/_static/img/icons/icon-mail-list.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-manager.svg b/stable/_static/img/icons/icon-manager.svg new file mode 100644 index 00000000..02b4e425 --- /dev/null +++ b/stable/_static/img/icons/icon-manager.svg @@ -0,0 +1 @@ +icon-manager diff --git a/stable/_static/img/icons/icon-memory-management.svg b/stable/_static/img/icons/icon-memory-management.svg new file mode 100644 index 00000000..e34eb450 --- /dev/null +++ b/stable/_static/img/icons/icon-memory-management.svg @@ -0,0 +1 @@ +icon-memory-management diff --git a/stable/_static/img/icons/icon-modeling.svg b/stable/_static/img/icons/icon-modeling.svg new file mode 100644 index 00000000..97fa3a0e --- /dev/null +++ b/stable/_static/img/icons/icon-modeling.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-monitoring.svg b/stable/_static/img/icons/icon-monitoring.svg new file mode 100644 index 00000000..80b3787f --- /dev/null +++ b/stable/_static/img/icons/icon-monitoring.svg @@ -0,0 +1 @@ +icon-monitoring diff --git a/stable/_static/img/icons/icon-networking.svg b/stable/_static/img/icons/icon-networking.svg new file mode 100644 index 00000000..40a3fd5f --- /dev/null +++ b/stable/_static/img/icons/icon-networking.svg @@ -0,0 +1 @@ +icon-networking diff --git a/stable/_static/img/icons/icon-news.svg b/stable/_static/img/icons/icon-news.svg new file mode 100644 index 00000000..a952b599 --- /dev/null +++ b/stable/_static/img/icons/icon-news.svg @@ -0,0 +1 @@ +icon-news diff --git a/stable/_static/img/icons/icon-newsletter.svg b/stable/_static/img/icons/icon-newsletter.svg new file mode 100644 index 00000000..5b8d47eb --- /dev/null +++ b/stable/_static/img/icons/icon-newsletter.svg @@ -0,0 +1 @@ +icon-newsletter diff --git a/stable/_static/img/icons/icon-nsql-guides.svg b/stable/_static/img/icons/icon-nsql-guides.svg new file mode 100644 index 00000000..60ebab37 --- /dev/null +++ b/stable/_static/img/icons/icon-nsql-guides.svg @@ -0,0 +1 @@ +icon-nsql-guides diff --git a/stable/_static/img/icons/icon-open-source.svg b/stable/_static/img/icons/icon-open-source.svg new file mode 100644 index 00000000..98c2ea7d --- /dev/null +++ b/stable/_static/img/icons/icon-open-source.svg @@ -0,0 +1 @@ +icon-open-source diff --git a/stable/_static/img/icons/icon-operator.svg b/stable/_static/img/icons/icon-operator.svg new file mode 100644 index 00000000..bb7d8d3e --- /dev/null +++ b/stable/_static/img/icons/icon-operator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/icons/icon-overview.svg b/stable/_static/img/icons/icon-overview.svg new file mode 100644 index 00000000..515c1528 --- /dev/null +++ b/stable/_static/img/icons/icon-overview.svg @@ -0,0 +1 @@ +icon-overview diff --git a/stable/_static/img/icons/icon-partners.svg b/stable/_static/img/icons/icon-partners.svg new file mode 100644 index 00000000..d0146fc4 --- /dev/null +++ b/stable/_static/img/icons/icon-partners.svg @@ -0,0 +1 @@ +icon-partners diff --git a/stable/_static/img/icons/icon-plus.svg b/stable/_static/img/icons/icon-plus.svg new file mode 100644 index 00000000..57574350 --- /dev/null +++ b/stable/_static/img/icons/icon-plus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/stable/_static/img/icons/icon-pricing.svg b/stable/_static/img/icons/icon-pricing.svg new file mode 100644 index 00000000..74b01db1 --- /dev/null +++ b/stable/_static/img/icons/icon-pricing.svg @@ -0,0 +1 @@ +icon-pricing$ diff --git a/stable/_static/img/icons/icon-release-notes.svg b/stable/_static/img/icons/icon-release-notes.svg new file mode 100644 index 00000000..80c490c7 --- /dev/null +++ b/stable/_static/img/icons/icon-release-notes.svg @@ -0,0 +1 @@ +icon-release-notes diff --git a/stable/_static/img/icons/icon-resource-center.svg b/stable/_static/img/icons/icon-resource-center.svg new file mode 100644 index 00000000..6e3ab08e --- /dev/null +++ b/stable/_static/img/icons/icon-resource-center.svg @@ -0,0 +1 @@ +icon-ressource-center diff --git a/stable/_static/img/icons/icon-roadmap.svg b/stable/_static/img/icons/icon-roadmap.svg new file mode 100644 index 00000000..c8cbf67c --- /dev/null +++ b/stable/_static/img/icons/icon-roadmap.svg @@ -0,0 +1 @@ +icon-roadmap-4 diff --git a/stable/_static/img/icons/icon-search.svg b/stable/_static/img/icons/icon-search.svg new file mode 100644 index 00000000..81aae93e --- /dev/null +++ b/stable/_static/img/icons/icon-search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/stable/_static/img/icons/icon-slack.svg b/stable/_static/img/icons/icon-slack.svg new file mode 100644 index 00000000..fc164ea1 --- /dev/null +++ b/stable/_static/img/icons/icon-slack.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-stack-overflow.svg b/stable/_static/img/icons/icon-stack-overflow.svg new file mode 100644 index 00000000..bebe9b82 --- /dev/null +++ b/stable/_static/img/icons/icon-stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/stable/_static/img/icons/icon-summit.svg b/stable/_static/img/icons/icon-summit.svg new file mode 100644 index 00000000..4b900bd0 --- /dev/null +++ b/stable/_static/img/icons/icon-summit.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/icons/icon-support.svg b/stable/_static/img/icons/icon-support.svg new file mode 100644 index 00000000..a4228b34 --- /dev/null +++ b/stable/_static/img/icons/icon-support.svg @@ -0,0 +1 @@ +icon-support diff --git a/stable/_static/img/icons/icon-tech-talks.svg b/stable/_static/img/icons/icon-tech-talks.svg new file mode 100644 index 00000000..df42b552 --- /dev/null +++ b/stable/_static/img/icons/icon-tech-talks.svg @@ -0,0 +1 @@ +icon-tech-talks diff --git a/stable/_static/img/icons/icon-testing.svg b/stable/_static/img/icons/icon-testing.svg new file mode 100644 index 00000000..2fe54efd --- /dev/null +++ b/stable/_static/img/icons/icon-testing.svg @@ -0,0 +1 @@ +icon-testing diff --git a/stable/_static/img/icons/icon-thumbs-down.svg b/stable/_static/img/icons/icon-thumbs-down.svg new file mode 100644 index 00000000..3e7bcd6d --- /dev/null +++ b/stable/_static/img/icons/icon-thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/icons/icon-thumbs-up.svg b/stable/_static/img/icons/icon-thumbs-up.svg new file mode 100644 index 00000000..226c44d8 --- /dev/null +++ b/stable/_static/img/icons/icon-thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/icons/icon-tip.svg b/stable/_static/img/icons/icon-tip.svg new file mode 100644 index 00000000..bf7aa6af --- /dev/null +++ b/stable/_static/img/icons/icon-tip.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/stable/_static/img/icons/icon-training.svg b/stable/_static/img/icons/icon-training.svg new file mode 100644 index 00000000..08b95a88 --- /dev/null +++ b/stable/_static/img/icons/icon-training.svg @@ -0,0 +1 @@ +icon-training diff --git a/stable/_static/img/icons/icon-triangle-down.svg b/stable/_static/img/icons/icon-triangle-down.svg new file mode 100644 index 00000000..e8ae0881 --- /dev/null +++ b/stable/_static/img/icons/icon-triangle-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/stable/_static/img/icons/icon-university.svg b/stable/_static/img/icons/icon-university.svg new file mode 100644 index 00000000..f7547ab9 --- /dev/null +++ b/stable/_static/img/icons/icon-university.svg @@ -0,0 +1 @@ +icon-university diff --git a/stable/_static/img/icons/icon-users-blog.svg b/stable/_static/img/icons/icon-users-blog.svg new file mode 100644 index 00000000..47e56cdd --- /dev/null +++ b/stable/_static/img/icons/icon-users-blog.svg @@ -0,0 +1 @@ +icon-users-blog diff --git a/stable/_static/img/icons/icon-warning.svg b/stable/_static/img/icons/icon-warning.svg new file mode 100644 index 00000000..e4b1d403 --- /dev/null +++ b/stable/_static/img/icons/icon-warning.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/stable/_static/img/icons/icon-webinars.svg b/stable/_static/img/icons/icon-webinars.svg new file mode 100644 index 00000000..5e9f5cd4 --- /dev/null +++ b/stable/_static/img/icons/icon-webinars.svg @@ -0,0 +1 @@ +icon-webinars diff --git a/stable/_static/img/icons/icon-whitepapers.svg b/stable/_static/img/icons/icon-whitepapers.svg new file mode 100644 index 00000000..3351e51d --- /dev/null +++ b/stable/_static/img/icons/icon-whitepapers.svg @@ -0,0 +1 @@ +icon-whitepapers diff --git a/stable/_static/img/icons/icon-workshop.svg b/stable/_static/img/icons/icon-workshop.svg new file mode 100644 index 00000000..5206e58e --- /dev/null +++ b/stable/_static/img/icons/icon-workshop.svg @@ -0,0 +1 @@ + diff --git a/stable/_static/img/logo-docs.svg b/stable/_static/img/logo-docs.svg new file mode 100644 index 00000000..4fff669c --- /dev/null +++ b/stable/_static/img/logo-docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/_static/img/logo-scylla-horizontal-RGB.svg b/stable/_static/img/logo-scylla-horizontal-RGB.svg new file mode 100644 index 00000000..b5022d7c --- /dev/null +++ b/stable/_static/img/logo-scylla-horizontal-RGB.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stable/_static/img/mascots/404.jpg b/stable/_static/img/mascots/404.jpg new file mode 100644 index 00000000..769fa088 Binary files /dev/null and b/stable/_static/img/mascots/404.jpg differ diff --git a/stable/_static/img/mascots/scylla-3monsters.png b/stable/_static/img/mascots/scylla-3monsters.png new file mode 100644 index 00000000..7c06d016 Binary files /dev/null and b/stable/_static/img/mascots/scylla-3monsters.png differ diff --git a/stable/_static/img/mascots/scylla-advisor-crystal.png b/stable/_static/img/mascots/scylla-advisor-crystal.png new file mode 100644 index 00000000..d33fddd6 Binary files /dev/null and b/stable/_static/img/mascots/scylla-advisor-crystal.png differ diff --git a/stable/_static/img/mascots/scylla-alternator.svg b/stable/_static/img/mascots/scylla-alternator.svg new file mode 100644 index 00000000..0462f893 --- /dev/null +++ b/stable/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/stable/_static/img/mascots/scylla-care-pet-mascot.svg b/stable/_static/img/mascots/scylla-care-pet-mascot.svg new file mode 100644 index 00000000..8bb17041 --- /dev/null +++ b/stable/_static/img/mascots/scylla-care-pet-mascot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stable/_static/img/mascots/scylla-cloud.svg b/stable/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 00000000..a6c6a26f --- /dev/null +++ b/stable/_static/img/mascots/scylla-cloud.svg @@ -0,0 +1 @@ +scylla-cloud diff --git a/stable/_static/img/mascots/scylla-computer-3-monsters.png b/stable/_static/img/mascots/scylla-computer-3-monsters.png new file mode 100644 index 00000000..d0368a70 Binary files /dev/null and b/stable/_static/img/mascots/scylla-computer-3-monsters.png differ diff --git a/stable/_static/img/mascots/scylla-computer-headset.png b/stable/_static/img/mascots/scylla-computer-headset.png new file mode 100644 index 00000000..0cdadaa2 Binary files /dev/null and b/stable/_static/img/mascots/scylla-computer-headset.png differ diff --git a/stable/_static/img/mascots/scylla-cup-number-one.png b/stable/_static/img/mascots/scylla-cup-number-one.png new file mode 100644 index 00000000..e889f4e3 Binary files /dev/null and b/stable/_static/img/mascots/scylla-cup-number-one.png differ diff --git a/stable/_static/img/mascots/scylla-docs.svg b/stable/_static/img/mascots/scylla-docs.svg new file mode 100644 index 00000000..a5bce950 --- /dev/null +++ b/stable/_static/img/mascots/scylla-docs.svg @@ -0,0 +1 @@ +scylla-docs diff --git a/stable/_static/img/mascots/scylla-drivers.svg b/stable/_static/img/mascots/scylla-drivers.svg new file mode 100644 index 00000000..6012e716 --- /dev/null +++ b/stable/_static/img/mascots/scylla-drivers.svg @@ -0,0 +1 @@ +scylla-manager diff --git a/stable/_static/img/mascots/scylla-enterprise.svg b/stable/_static/img/mascots/scylla-enterprise.svg new file mode 100644 index 00000000..a1aa0b46 --- /dev/null +++ b/stable/_static/img/mascots/scylla-enterprise.svg @@ -0,0 +1 @@ +scylla-enterprise diff --git a/stable/_static/img/mascots/scylla-forklift-boxes.png b/stable/_static/img/mascots/scylla-forklift-boxes.png new file mode 100644 index 00000000..f64c29e6 Binary files /dev/null and b/stable/_static/img/mascots/scylla-forklift-boxes.png differ diff --git a/stable/_static/img/mascots/scylla-forklift-migration.png b/stable/_static/img/mascots/scylla-forklift-migration.png new file mode 100644 index 00000000..d2f645c6 Binary files /dev/null and b/stable/_static/img/mascots/scylla-forklift-migration.png differ diff --git a/stable/_static/img/mascots/scylla-gear.png b/stable/_static/img/mascots/scylla-gear.png new file mode 100644 index 00000000..0f53b26a Binary files /dev/null and b/stable/_static/img/mascots/scylla-gear.png differ diff --git a/stable/_static/img/mascots/scylla-hardhat.png b/stable/_static/img/mascots/scylla-hardhat.png new file mode 100644 index 00000000..630f2d90 Binary files /dev/null and b/stable/_static/img/mascots/scylla-hardhat.png differ diff --git a/stable/_static/img/mascots/scylla-headband.png b/stable/_static/img/mascots/scylla-headband.png new file mode 100644 index 00000000..c87abe68 Binary files /dev/null and b/stable/_static/img/mascots/scylla-headband.png differ diff --git a/stable/_static/img/mascots/scylla-headset.png b/stable/_static/img/mascots/scylla-headset.png new file mode 100644 index 00000000..ba52cd22 Binary files /dev/null and b/stable/_static/img/mascots/scylla-headset.png differ diff --git a/stable/_static/img/mascots/scylla-hearts.png b/stable/_static/img/mascots/scylla-hearts.png new file mode 100644 index 00000000..cef08c86 Binary files /dev/null and b/stable/_static/img/mascots/scylla-hearts.png differ diff --git a/stable/_static/img/mascots/scylla-looking-down.png b/stable/_static/img/mascots/scylla-looking-down.png new file mode 100644 index 00000000..75cccbfd Binary files /dev/null and b/stable/_static/img/mascots/scylla-looking-down.png differ diff --git a/stable/_static/img/mascots/scylla-looking-up.png b/stable/_static/img/mascots/scylla-looking-up.png new file mode 100644 index 00000000..6f10405f Binary files /dev/null and b/stable/_static/img/mascots/scylla-looking-up.png differ diff --git a/stable/_static/img/mascots/scylla-magnifying-glass-fronting.png b/stable/_static/img/mascots/scylla-magnifying-glass-fronting.png new file mode 100644 index 00000000..e368cae1 Binary files /dev/null and b/stable/_static/img/mascots/scylla-magnifying-glass-fronting.png differ diff --git a/stable/_static/img/mascots/scylla-magnifying-glass.png b/stable/_static/img/mascots/scylla-magnifying-glass.png new file mode 100644 index 00000000..74ad6695 Binary files /dev/null and b/stable/_static/img/mascots/scylla-magnifying-glass.png differ diff --git a/stable/_static/img/mascots/scylla-manager.svg b/stable/_static/img/mascots/scylla-manager.svg new file mode 100644 index 00000000..6ba9ed93 --- /dev/null +++ b/stable/_static/img/mascots/scylla-manager.svg @@ -0,0 +1 @@ +scylla-manager-2 diff --git a/stable/_static/img/mascots/scylla-monitor.svg b/stable/_static/img/mascots/scylla-monitor.svg new file mode 100644 index 00000000..48bec7dd --- /dev/null +++ b/stable/_static/img/mascots/scylla-monitor.svg @@ -0,0 +1 @@ +scylla-monitor diff --git a/stable/_static/img/mascots/scylla-movement-fast.png b/stable/_static/img/mascots/scylla-movement-fast.png new file mode 100644 index 00000000..956d1dd0 Binary files /dev/null and b/stable/_static/img/mascots/scylla-movement-fast.png differ diff --git a/stable/_static/img/mascots/scylla-movement.png b/stable/_static/img/mascots/scylla-movement.png new file mode 100644 index 00000000..7ee2b043 Binary files /dev/null and b/stable/_static/img/mascots/scylla-movement.png differ diff --git a/stable/_static/img/mascots/scylla-onpremise.png b/stable/_static/img/mascots/scylla-onpremise.png new file mode 100644 index 00000000..3b2dc8f1 Binary files /dev/null and b/stable/_static/img/mascots/scylla-onpremise.png differ diff --git a/stable/_static/img/mascots/scylla-opensource.svg b/stable/_static/img/mascots/scylla-opensource.svg new file mode 100644 index 00000000..299e9cb9 --- /dev/null +++ b/stable/_static/img/mascots/scylla-opensource.svg @@ -0,0 +1 @@ +Plan de travail 1 diff --git a/stable/_static/img/mascots/scylla-operator.svg b/stable/_static/img/mascots/scylla-operator.svg new file mode 100644 index 00000000..655a450b --- /dev/null +++ b/stable/_static/img/mascots/scylla-operator.svg @@ -0,0 +1 @@ +scylla-operator diff --git a/stable/_static/img/mascots/scylla-plugin.png b/stable/_static/img/mascots/scylla-plugin.png new file mode 100644 index 00000000..b28dc857 Binary files /dev/null and b/stable/_static/img/mascots/scylla-plugin.png differ diff --git a/stable/_static/img/mascots/scylla-release-mascot.png b/stable/_static/img/mascots/scylla-release-mascot.png new file mode 100644 index 00000000..09342ac6 Binary files /dev/null and b/stable/_static/img/mascots/scylla-release-mascot.png differ diff --git a/stable/_static/img/mascots/scylla-repair.png b/stable/_static/img/mascots/scylla-repair.png new file mode 100644 index 00000000..9b4c613e Binary files /dev/null and b/stable/_static/img/mascots/scylla-repair.png differ diff --git a/stable/_static/img/mascots/scylla-server.png b/stable/_static/img/mascots/scylla-server.png new file mode 100644 index 00000000..96dc7852 Binary files /dev/null and b/stable/_static/img/mascots/scylla-server.png differ diff --git a/stable/_static/img/mascots/scylla-sleeping.png b/stable/_static/img/mascots/scylla-sleeping.png new file mode 100644 index 00000000..f88598e0 Binary files /dev/null and b/stable/_static/img/mascots/scylla-sleeping.png differ diff --git a/stable/_static/img/mascots/scylla-tall-measure.png b/stable/_static/img/mascots/scylla-tall-measure.png new file mode 100644 index 00000000..6f0ca146 Binary files /dev/null and b/stable/_static/img/mascots/scylla-tall-measure.png differ diff --git a/stable/_static/img/mascots/scylla-university.png b/stable/_static/img/mascots/scylla-university.png new file mode 100644 index 00000000..b3d06211 Binary files /dev/null and b/stable/_static/img/mascots/scylla-university.png differ diff --git a/stable/_static/img/mascots/scylla-weights.png b/stable/_static/img/mascots/scylla-weights.png new file mode 100644 index 00000000..b070bb02 Binary files /dev/null and b/stable/_static/img/mascots/scylla-weights.png differ diff --git a/stable/_static/img/mascots/scylla-window-cleaning.png b/stable/_static/img/mascots/scylla-window-cleaning.png new file mode 100644 index 00000000..6a8b16a6 Binary files /dev/null and b/stable/_static/img/mascots/scylla-window-cleaning.png differ diff --git a/stable/_static/img/mascots/scylla-with-computer-2.png b/stable/_static/img/mascots/scylla-with-computer-2.png new file mode 100644 index 00000000..f3b8b298 Binary files /dev/null and b/stable/_static/img/mascots/scylla-with-computer-2.png differ diff --git a/stable/_static/img/mascots/scylla-with-computer.png b/stable/_static/img/mascots/scylla-with-computer.png new file mode 100644 index 00000000..b38a6fbb Binary files /dev/null and b/stable/_static/img/mascots/scylla-with-computer.png differ diff --git a/stable/_static/img/mascots/scylla-with-linux.png b/stable/_static/img/mascots/scylla-with-linux.png new file mode 100644 index 00000000..954bf13b Binary files /dev/null and b/stable/_static/img/mascots/scylla-with-linux.png differ diff --git a/stable/_static/img/mascots/scylla-writting.png b/stable/_static/img/mascots/scylla-writting.png new file mode 100644 index 00000000..d35a13d3 Binary files /dev/null and b/stable/_static/img/mascots/scylla-writting.png differ diff --git a/stable/_static/img/menu.svg b/stable/_static/img/menu.svg new file mode 100644 index 00000000..30ea1d90 --- /dev/null +++ b/stable/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/stable/_static/img/programming_languages/go-lang.png b/stable/_static/img/programming_languages/go-lang.png new file mode 100644 index 00000000..57006b20 Binary files /dev/null and b/stable/_static/img/programming_languages/go-lang.png differ diff --git a/stable/_static/img/programming_languages/java.png b/stable/_static/img/programming_languages/java.png new file mode 100644 index 00000000..f9639c93 Binary files /dev/null and b/stable/_static/img/programming_languages/java.png differ diff --git a/stable/_static/img/programming_languages/javascript.png b/stable/_static/img/programming_languages/javascript.png new file mode 100644 index 00000000..9bca9f37 Binary files /dev/null and b/stable/_static/img/programming_languages/javascript.png differ diff --git a/stable/_static/img/programming_languages/php.png b/stable/_static/img/programming_languages/php.png new file mode 100644 index 00000000..951bf70a Binary files /dev/null and b/stable/_static/img/programming_languages/php.png differ diff --git a/stable/_static/img/programming_languages/python.png b/stable/_static/img/programming_languages/python.png new file mode 100644 index 00000000..0577e602 Binary files /dev/null and b/stable/_static/img/programming_languages/python.png differ diff --git a/stable/_static/img/programming_languages/rust.png b/stable/_static/img/programming_languages/rust.png new file mode 100644 index 00000000..b3d56391 Binary files /dev/null and b/stable/_static/img/programming_languages/rust.png differ diff --git a/stable/_static/js/main.bundle.js b/stable/_static/js/main.bundle.js new file mode 100644 index 00000000..190a4164 --- /dev/null +++ b/stable/_static/js/main.bundle.js @@ -0,0 +1,2 @@ +/*! For license information please see main.bundle.js.LICENSE.txt */ +(self.webpackChunksphinx_scylladb_theme=self.webpackChunksphinx_scylladb_theme||[]).push([[179],{277:(t,e,n)=>{var i;self,i=function(t){return function(){"use strict";var e={"./js/foundation.abide.js":function(t,e,n){n.r(e),n.d(e,{Abide:function(){return f}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.plugin.js"),s=n("./js/foundation.core.utils.js");function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}function l(t,e){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{};this.$element=t,this.options=o().extend(!0,{},d.defaults,this.$element.data(),e),this.isEnabled=!0,this.formnovalidate=null,this.className="Abide",this._init()}},{key:"_init",value:function(){var t=this;this.$inputs=o().merge(this.$element.find("input").not('[type="submit"]'),this.$element.find("textarea, select")),this.$submits=this.$element.find('[type="submit"]');var e=this.$element.find("[data-abide-error]");this.options.a11yAttributes&&(this.$inputs.each((function(e,n){return t.addA11yAttributes(o()(n))})),e.each((function(e,n){return t.addGlobalErrorA11yAttributes(o()(n))}))),this._events()}},{key:"_events",value:function(){var t=this;this.$element.off(".abide").on("reset.zf.abide",(function(){t.resetForm()})).on("submit.zf.abide",(function(){return t.validateForm()})),this.$submits.off("click.zf.abide keydown.zf.abide").on("click.zf.abide keydown.zf.abide",(function(e){e.key&&" "!==e.key&&"Enter"!==e.key||(e.preventDefault(),t.formnovalidate=null!==e.target.getAttribute("formnovalidate"),t.$element.submit())})),"fieldChange"===this.options.validateOn&&this.$inputs.off("change.zf.abide").on("change.zf.abide",(function(e){t.validateInput(o()(e.target))})),this.options.liveValidate&&this.$inputs.off("input.zf.abide").on("input.zf.abide",(function(e){t.validateInput(o()(e.target))})),this.options.validateOnBlur&&this.$inputs.off("blur.zf.abide").on("blur.zf.abide",(function(e){t.validateInput(o()(e.target))}))}},{key:"_reflow",value:function(){this._init()}},{key:"_validationIsDisabled",value:function(){return!1===this.isEnabled||("boolean"==typeof this.formnovalidate?this.formnovalidate:!!this.$submits.length&&null!==this.$submits[0].getAttribute("formnovalidate"))}},{key:"enableValidation",value:function(){this.isEnabled=!0}},{key:"disableValidation",value:function(){this.isEnabled=!1}},{key:"requiredCheck",value:function(t){if(!t.attr("required"))return!0;var e=!0;switch(t[0].type){case"checkbox":e=t[0].checked;break;case"select":case"select-one":case"select-multiple":var n=t.find("option:selected");n.length&&n.val()||(e=!1);break;default:t.val()&&t.val().length||(e=!1)}return e}},{key:"findFormError",value:function(t,e){var n=this,i=t.length?t[0].id:"",o=t.siblings(this.options.formErrorSelector);return o.length||(o=t.parent().find(this.options.formErrorSelector)),i&&(o=o.add(this.$element.find('[data-form-error-for="'.concat(i,'"]')))),e&&(o=o.not("[data-form-error-on]"),e.forEach((function(e){o=(o=o.add(t.siblings('[data-form-error-on="'.concat(e,'"]')))).add(n.$element.find('[data-form-error-for="'.concat(i,'"][data-form-error-on="').concat(e,'"]')))}))),o}},{key:"findLabel",value:function(t){var e=t[0].id,n=this.$element.find('label[for="'.concat(e,'"]'));return n.length?n:t.closest("label")}},{key:"findRadioLabels",value:function(t){var e=this,n=t.map((function(t,n){var i=n.id,r=e.$element.find('label[for="'.concat(i,'"]'));return r.length||(r=o()(n).closest("label")),r[0]}));return o()(n)}},{key:"findCheckboxLabels",value:function(t){var e=this,n=t.map((function(t,n){var i=n.id,r=e.$element.find('label[for="'.concat(i,'"]'));return r.length||(r=o()(n).closest("label")),r[0]}));return o()(n)}},{key:"addErrorClasses",value:function(t,e){var n=this.findLabel(t),i=this.findFormError(t,e);n.length&&n.addClass(this.options.labelErrorClass),i.length&&i.addClass(this.options.formErrorClass),t.addClass(this.options.inputErrorClass).attr({"data-invalid":"","aria-invalid":!0}),i.filter(":visible").length&&this.addA11yErrorDescribe(t,i)}},{key:"addA11yAttributes",value:function(t){var e=this.findFormError(t),n=e.filter("label");if(e.length){var i=e.filter(":visible").first();if(i.length&&this.addA11yErrorDescribe(t,i),n.filter("[for]").length=s&&(i=!0)),!0!==this.initialized&&s>1||(n.each((function(t,n){i?e.removeErrorClasses(o()(n)):e.addErrorClasses(o()(n),["required"])})),i)}},{key:"matchValidation",value:function(t,e,n){var i=this;return n=!!n,-1===e.split(" ").map((function(e){return i.options.validators[e](t,n,t.parent())})).indexOf(!1)}},{key:"resetForm",value:function(){var t=this.$element,e=this.options;o()(".".concat(e.labelErrorClass),t).not("small").removeClass(e.labelErrorClass),o()(".".concat(e.inputErrorClass),t).not("small").removeClass(e.inputErrorClass),o()("".concat(e.formErrorSelector,".").concat(e.formErrorClass)).removeClass(e.formErrorClass),t.find("[data-abide-error]").css("display","none"),o()(":input",t).not(":button, :submit, :reset, :hidden, :radio, :checkbox, [data-abide-ignore]").val("").attr({"data-invalid":null,"aria-invalid":null}),o()(":input:radio",t).not("[data-abide-ignore]").prop("checked",!1).attr({"data-invalid":null,"aria-invalid":null}),o()(":input:checkbox",t).not("[data-abide-ignore]").prop("checked",!1).attr({"data-invalid":null,"aria-invalid":null}),t.trigger("formreset.zf.abide",[t])}},{key:"_destroy",value:function(){var t=this;this.$element.off(".abide").find("[data-abide-error]").css("display","none"),this.$inputs.off(".abide").each((function(){t.removeErrorClasses(o()(this))})),this.$submits.off(".abide")}}],n&&l(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),d}(r.Plugin);f.defaults={validateOn:"fieldChange",labelErrorClass:"is-invalid-label",inputErrorClass:"is-invalid-input",formErrorSelector:".form-error",formErrorClass:"is-visible",a11yAttributes:!0,a11yErrorLevel:"assertive",liveValidate:!1,validateOnBlur:!1,patterns:{alpha:/^[a-zA-Z]+$/,alpha_numeric:/^[a-zA-Z0-9]+$/,integer:/^[-+]?\d+$/,number:/^[-+]?\d*(?:[\.\,]\d+)?$/,card:/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(?:222[1-9]|2[3-6][0-9]{2}|27[0-1][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,cvv:/^([0-9]){3,4}$/,email:/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/,url:/^((?:(https?|ftps?|file|ssh|sftp):\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\))+(?:\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?\xab\xbb\u201c\u201d\u2018\u2019]))$/,domain:/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/,datetime:/^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/,date:/(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/,time:/^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/,dateISO:/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/,month_day_year:/^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/,day_month_year:/^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/,color:/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,website:{test:function(t){return f.defaults.patterns.domain.test(t)||f.defaults.patterns.url.test(t)}}},validators:{equalTo:function(t){return o()("#".concat(t.attr("data-equalto"))).val()===t.val()}}}},"./js/foundation.accordion.js":function(t,e,n){n.r(e),n.d(e,{Accordion:function(){return d}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.plugin.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.util.keyboard.js");function l(t){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},l(t)}function u(t,e){for(var n=0;n'),t.options.submenuToggle?(n.addClass("has-submenu-toggle"),n.children("a").after('")):n.attr({"aria-controls":r,"aria-expanded":s,id:e}),i.attr({"aria-labelledby":e,"aria-hidden":!s,role:"group",id:r})}));var e=this.$element.find(".is-active");e.length&&e.each((function(){t.down(o()(this))})),this._events()}},{key:"_events",value:function(){var t=this;this.$element.find("li").each((function(){var e=o()(this).children("[data-submenu]");e.length&&(t.options.submenuToggle?o()(this).children(".submenu-toggle").off("click.zf.accordionMenu").on("click.zf.accordionMenu",(function(){t.toggle(e)})):o()(this).children("a").off("click.zf.accordionMenu").on("click.zf.accordionMenu",(function(n){n.preventDefault(),t.toggle(e)})))})).on("keydown.zf.accordionMenu",(function(e){var n,i,s=o()(this),a=s.parent("ul").children("li"),l=s.children("[data-submenu]");a.each((function(t){if(o()(this).is(s))return n=a.eq(Math.max(0,t-1)).find("a").first(),i=a.eq(Math.min(t+1,a.length-1)).find("a").first(),o()(this).children("[data-submenu]:visible").length&&(i=s.find("li:first-child").find("a").first()),o()(this).is(":first-child")?n=s.parents("li").first().find("a").first():n.parents("li").first().children("[data-submenu]:visible").length&&(n=n.parents("li").find("li:last-child").find("a").first()),void(o()(this).is(":last-child")&&(i=s.parents("li").first().next("li").find("a").first()))})),r.Keyboard.handleKey(e,"AccordionMenu",{open:function(){l.is(":hidden")&&(t.down(l),l.find("li").first().find("a").first().focus())},close:function(){l.length&&!l.is(":hidden")?t.up(l):s.parent("[data-submenu]").length&&(t.up(s.parent("[data-submenu]")),s.parents("li").first().find("a").first().focus())},up:function(){return n.focus(),!0},down:function(){return i.focus(),!0},toggle:function(){return!t.options.submenuToggle&&(s.children("[data-submenu]").length?(t.toggle(s.children("[data-submenu]")),!0):void 0)},closeAll:function(){t.hideAll()},handled:function(t){t&&e.preventDefault()}})}))}},{key:"hideAll",value:function(){this.up(this.$element.find("[data-submenu]"))}},{key:"showAll",value:function(){this.down(this.$element.find("[data-submenu]"))}},{key:"toggle",value:function(t){t.is(":animated")||(t.is(":hidden")?this.down(t):this.up(t))}},{key:"down",value:function(t){var e=this;if(!this.options.multiOpen){var n=t.parentsUntil(this.$element).add(t).add(t.find(".is-active")),i=this.$element.find(".is-active").not(n);this.up(i)}t.addClass("is-active").attr({"aria-hidden":!1}),this.options.submenuToggle?t.prev(".submenu-toggle").attr({"aria-expanded":!0}):t.parent(".is-accordion-submenu-parent").attr({"aria-expanded":!0}),t.slideDown(this.options.slideSpeed,(function(){e.$element.trigger("down.zf.accordionMenu",[t])}))}},{key:"up",value:function(t){var e=this,n=t.find("[data-submenu]"),i=t.add(n);n.slideUp(0),i.removeClass("is-active").attr("aria-hidden",!0),this.options.submenuToggle?i.prev(".submenu-toggle").attr("aria-expanded",!1):i.parent(".is-accordion-submenu-parent").attr("aria-expanded",!1),t.slideUp(this.options.slideSpeed,(function(){e.$element.trigger("up.zf.accordionMenu",[t])}))}},{key:"_destroy",value:function(){this.$element.find("[data-submenu]").slideDown(0).css("display",""),this.$element.find("a").off("click.zf.accordionMenu"),this.$element.find("[data-is-parent-link]").detach(),this.options.submenuToggle&&(this.$element.find(".has-submenu-toggle").removeClass("has-submenu-toggle"),this.$element.find(".submenu-toggle").remove()),s.Nest.Burn(this.$element,"accordion")}}])&&u(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),p}(n("./js/foundation.core.plugin.js").Plugin);d.defaults={parentLink:!1,slideSpeed:250,submenuToggle:!1,submenuToggleText:"Toggle menu",multiOpen:!0}},"./js/foundation.core.js":function(t,e,n){n.r(e),n.d(e,{Foundation:function(){return l}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.utils.js"),s=n("./js/foundation.util.mediaQuery.js");function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}var l={version:"6.8.1",_plugins:{},_uuids:[],plugin:function(t,e){var n=e||u(t),i=c(n);this._plugins[i]=this[n]=t},registerPlugin:function(t,e){var n=e?c(e):u(t.constructor).toLowerCase();t.uuid=(0,r.GetYoDigits)(6,n),t.$element.attr("data-".concat(n))||t.$element.attr("data-".concat(n),t.uuid),t.$element.data("zfPlugin")||t.$element.data("zfPlugin",t),t.$element.trigger("init.zf.".concat(n)),this._uuids.push(t.uuid)},unregisterPlugin:function(t){var e=c(u(t.$element.data("zfPlugin").constructor));for(var n in this._uuids.splice(this._uuids.indexOf(t.uuid),1),t.$element.removeAttr("data-".concat(e)).removeData("zfPlugin").trigger("destroyed.zf.".concat(e)),t)"function"==typeof t[n]&&(t[n]=null)},reInit:function(t){var e=t instanceof o();try{if(e)t.each((function(){o()(this).data("zfPlugin")._init()}));else{var n=a(t),i=this;({object:function(t){t.forEach((function(t){t=c(t),o()("[data-"+t+"]").foundation("_init")}))},string:function(){t=c(t),o()("[data-"+t+"]").foundation("_init")},undefined:function(){this.object(Object.keys(i._plugins))}})[n](t)}}catch(t){console.error(t)}finally{return t}},reflow:function(t,e){void 0===e?e=Object.keys(this._plugins):"string"==typeof e&&(e=[e]);var n=this;o().each(e,(function(e,i){var r=n._plugins[i];o()(t).find("[data-"+i+"]").addBack("[data-"+i+"]").filter((function(){return void 0===o()(this).data("zfPlugin")})).each((function(){var t=o()(this),e={reflow:!0};t.attr("data-options")&&t.attr("data-options").split(";").forEach((function(t){var n,i=t.split(":").map((function(t){return t.trim()}));i[0]&&(e[i[0]]="true"===(n=i[1])||"false"!==n&&(isNaN(1*n)?n:parseFloat(n)))}));try{t.data("zfPlugin",new r(o()(this),e))}catch(t){console.error(t)}finally{return}}))}))},getFnName:u,addToJquery:function(){return o().fn.foundation=function(t){var e=a(t),n=o()(".no-js");if(n.length&&n.removeClass("no-js"),"undefined"===e)s.MediaQuery._init(),l.reflow(this);else{if("string"!==e)throw new TypeError("We're sorry, ".concat(e," is not a valid parameter. You must use a string representing the method you wish to invoke."));var i=Array.prototype.slice.call(arguments,1),r=this.data("zfPlugin");if(void 0===r||void 0===r[t])throw new ReferenceError("We're sorry, '"+t+"' is not an available method for "+(r?u(r):"this element")+".");1===this.length?r[t].apply(r,i):this.each((function(e,n){r[t].apply(o()(n).data("zfPlugin"),i)}))}return this},o()}};function u(t){if(void 0===Function.prototype.name){var e=/function\s([^(]{1,})\(/.exec(t.toString());return e&&e.length>1?e[1].trim():""}return void 0===t.prototype?t.constructor.name:t.prototype.constructor.name}function c(t){return t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}l.util={throttle:function(t,e){var n=null;return function(){var i=this,o=arguments;null===n&&(n=setTimeout((function(){t.apply(i,o),n=null}),e))}}},window.Foundation=l,function(){Date.now&&window.Date.now||(window.Date.now=Date.now=function(){return(new Date).getTime()});for(var t=["webkit","moz"],e=0;e0&&void 0!==arguments[0]?arguments[0]:6,e=arguments.length>1?arguments[1]:void 0,n="",i="0123456789abcdefghijklmnopqrstuvwxyz",o=i.length,r=0;r1&&void 0!==arguments[1]?arguments[1]:{},n=e.ignoreLeaveWindow,i=void 0!==n&&n,r=e.ignoreReappear,s=void 0!==r&&r;return function(e){for(var n=arguments.length,r=new Array(n>1?n-1:0),a=1;a'),e.data("savedHref",e.attr("href")).removeAttr("href").attr("tabindex",0),e.children("[data-submenu]").attr({"aria-hidden":!0,tabindex:0,role:"group"}),t._events(e)})),this.$submenus.each((function(){var e=o()(this);if(!e.find(".js-drilldown-back").length)switch(t.options.backButtonPosition){case"bottom":e.append(t.options.backButton);break;case"top":e.prepend(t.options.backButton);break;default:console.error("Unsupported backButtonPosition value '"+t.options.backButtonPosition+"'")}t._back(e)})),this.$submenus.addClass("invisible"),this.options.autoHeight||this.$submenus.addClass("drilldown-submenu-cover-previous"),this.$element.parent().hasClass("is-drilldown")||(this.$wrapper=o()(this.options.wrapper).addClass("is-drilldown"),this.options.animateHeight&&this.$wrapper.addClass("animate-height"),this.$element.wrap(this.$wrapper)),this.$wrapper=this.$element.parent(),this.$wrapper.css(this._getMaxDims())}},{key:"_resize",value:function(){this.$wrapper.css({"max-width":"none","min-height":"none"}),this.$wrapper.css(this._getMaxDims())}},{key:"_events",value:function(t){var e=this;t.off("click.zf.drilldown").on("click.zf.drilldown",(function(n){if(o()(n.target).parentsUntil("ul","li").hasClass("is-drilldown-submenu-parent")&&n.preventDefault(),e._show(t.parent("li")),e.options.closeOnClick){var i=o()("body");i.off(".zf.drilldown").on("click.zf.drilldown",(function(t){t.target===e.$element[0]||o().contains(e.$element[0],t.target)||(t.preventDefault(),e._hideAll(),i.off(".zf.drilldown"))}))}}))}},{key:"_registerEvents",value:function(){this.options.scrollTop&&(this._bindHandler=this._scrollTop.bind(this),this.$element.on("open.zf.drilldown hide.zf.drilldown close.zf.drilldown closed.zf.drilldown",this._bindHandler)),this.$element.on("mutateme.zf.trigger",this._resize.bind(this))}},{key:"_scrollTop",value:function(){var t=this,e=""!==t.options.scrollTopElement?o()(t.options.scrollTopElement):t.$element,n=parseInt(e.offset().top+t.options.scrollTopOffset,10);o()("html, body").stop(!0).animate({scrollTop:n},t.options.animationDuration,t.options.animationEasing,(function(){this===o()("html")[0]&&t.$element.trigger("scrollme.zf.drilldown")}))}},{key:"_keyboardEvents",value:function(){var t=this;this.$menuItems.add(this.$element.find(".js-drilldown-back > a, .is-submenu-parent-item > a")).on("keydown.zf.drilldown",(function(e){var n,i,s=o()(this),l=s.parent("li").parent("ul").children("li").children("a");l.each((function(t){if(o()(this).is(s))return n=l.eq(Math.max(0,t-1)),void(i=l.eq(Math.min(t+1,l.length-1)))})),r.Keyboard.handleKey(e,"Drilldown",{next:function(){if(s.is(t.$submenuAnchors))return t._show(s.parent("li")),s.parent("li").one((0,a.transitionend)(s),(function(){s.parent("li").find("ul li a").not(".js-drilldown-back a").first().focus()})),!0},previous:function(){return t._hide(s.parent("li").parent("ul")),s.parent("li").parent("ul").one((0,a.transitionend)(s),(function(){setTimeout((function(){s.parent("li").parent("ul").parent("li").children("a").first().focus()}),1)})),!0},up:function(){return n.focus(),!s.is(t.$element.find("> li:first-child > a"))},down:function(){return i.focus(),!s.is(t.$element.find("> li:last-child > a"))},close:function(){s.is(t.$element.find("> li > a"))||(t._hide(s.parent().parent()),s.parent().parent().siblings("a").focus())},open:function(){return(!t.options.parentLink||!s.attr("href"))&&(s.is(t.$menuItems)?s.is(t.$submenuAnchors)?(t._show(s.parent("li")),s.parent("li").one((0,a.transitionend)(s),(function(){s.parent("li").find("ul li a").not(".js-drilldown-back a").first().focus()})),!0):void 0:(t._hide(s.parent("li").parent("ul")),s.parent("li").parent("ul").one((0,a.transitionend)(s),(function(){setTimeout((function(){s.parent("li").parent("ul").parent("li").children("a").first().focus()}),1)})),!0))},handled:function(t){t&&e.preventDefault()}})}))}},{key:"_hideAll",value:function(){var t=this,e=this.$element.find(".is-drilldown-submenu.is-active");if(e.addClass("is-closing"),e.parent().closest("ul").removeClass("invisible"),this.options.autoHeight){var n=e.parent().closest("ul").data("calcHeight");this.$wrapper.css({height:n})}this.$element.trigger("close.zf.drilldown"),e.one((0,a.transitionend)(e),(function(){e.removeClass("is-active is-closing"),t.$element.trigger("closed.zf.drilldown")}))}},{key:"_back",value:function(t){var e=this;t.off("click.zf.drilldown"),t.children(".js-drilldown-back").on("click.zf.drilldown",(function(){e._hide(t);var n=t.parent("li").parent("ul").parent("li");n.length?e._show(n):e.$currentMenu=e.$element}))}},{key:"_menuLinkEvents",value:function(){var t=this;this.$menuItems.not(".is-drilldown-submenu-parent").off("click.zf.drilldown").on("click.zf.drilldown",(function(){setTimeout((function(){t._hideAll()}),0)}))}},{key:"_setShowSubMenuClasses",value:function(t,e){t.addClass("is-active").removeClass("invisible").attr("aria-hidden",!1),t.parent("li").attr("aria-expanded",!0),!0===e&&this.$element.trigger("open.zf.drilldown",[t])}},{key:"_setHideSubMenuClasses",value:function(t,e){t.removeClass("is-active").addClass("invisible").attr("aria-hidden",!0),t.parent("li").attr("aria-expanded",!1),!0===e&&t.trigger("hide.zf.drilldown",[t])}},{key:"_showMenu",value:function(t,e){var n=this;if(this.$element.find('li[aria-expanded="true"] > ul[data-submenu]').each((function(){n._setHideSubMenuClasses(o()(this))})),this.$currentMenu=t,t.is("[data-drilldown]"))return!0===e&&t.find("li > a").first().focus(),void(this.options.autoHeight&&this.$wrapper.css("height",t.data("calcHeight")));var i=t.children().first().parentsUntil("[data-drilldown]","[data-submenu]");i.each((function(r){0===r&&n.options.autoHeight&&n.$wrapper.css("height",o()(this).data("calcHeight"));var s=r===i.length-1;!0===s&&o()(this).one((0,a.transitionend)(o()(this)),(function(){!0===e&&t.find("li > a").first().focus()})),n._setShowSubMenuClasses(o()(this),s)}))}},{key:"_show",value:function(t){var e=t.children("[data-submenu]");t.attr("aria-expanded",!0),this.$currentMenu=e,t.parent().closest("ul").addClass("invisible"),e.addClass("is-active visible").removeClass("invisible").attr("aria-hidden",!1),this.options.autoHeight&&this.$wrapper.css({height:e.data("calcHeight")}),this.$element.trigger("open.zf.drilldown",[t])}},{key:"_hide",value:function(t){this.options.autoHeight&&this.$wrapper.css({height:t.parent().closest("ul").data("calcHeight")}),t.parent().closest("ul").removeClass("invisible"),t.parent("li").attr("aria-expanded",!1),t.attr("aria-hidden",!0),t.addClass("is-closing").one((0,a.transitionend)(t),(function(){t.removeClass("is-active is-closing visible"),t.blur().addClass("invisible")})),t.trigger("hide.zf.drilldown",[t])}},{key:"_getMaxDims",value:function(){var t=0,e={},n=this;return this.$submenus.add(this.$element).each((function(){var e=l.Box.GetDimensions(this).height;t=e>t?e:t,n.options.autoHeight&&o()(this).data("calcHeight",e)})),this.options.autoHeight?e.height=this.$currentMenu.data("calcHeight"):e["min-height"]="".concat(t,"px"),e["max-width"]="".concat(this.$element[0].getBoundingClientRect().width,"px"),e}},{key:"_destroy",value:function(){o()("body").off(".zf.drilldown"),this.options.scrollTop&&this.$element.off(".zf.drilldown",this._bindHandler),this._hideAll(),this.$element.off("mutateme.zf.trigger"),s.Nest.Burn(this.$element,"drilldown"),this.$element.unwrap().find(".js-drilldown-back, .is-submenu-parent-item").remove().end().find(".is-active, .is-closing, .is-drilldown-submenu").removeClass("is-active is-closing is-drilldown-submenu").off("transitionend otransitionend webkitTransitionEnd").end().find("[data-submenu]").removeAttr("aria-hidden tabindex role"),this.$submenuAnchors.each((function(){o()(this).off(".zf.drilldown")})),this.$element.find("[data-is-parent-link]").detach(),this.$submenus.removeClass("drilldown-submenu-cover-previous invisible"),this.$element.find("a").each((function(){var t=o()(this);t.removeAttr("tabindex"),t.data("savedHref")&&t.attr("href",t.data("savedHref")).removeData("savedHref")}))}}])&&c(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),v}(n("./js/foundation.core.plugin.js").Plugin);h.defaults={autoApplyClass:!0,backButton:'
    • Back
    • ',backButtonPosition:"top",wrapper:"
      ",parentLink:!1,closeOnClick:!1,autoHeight:!1,animateHeight:!1,scrollTop:!1,scrollTopElement:"",scrollTopOffset:0,animationDuration:500,animationEasing:"swing"}},"./js/foundation.dropdown.js":function(t,e,n){n.r(e),n.d(e,{Dropdown:function(){return v}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.keyboard.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.positionable.js"),l=n("./js/foundation.util.triggers.js"),u=n("./js/foundation.util.touch.js");function c(t){return c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},c(t)}function f(t,e){for(var n=0;n-1,l=s?t.$tabs:r.siblings("li").add(r);l.each((function(t){if(o()(this).is(r))return n=l.eq(t-1),void(i=l.eq(t+1))}));var u=function(){i.children("a:first").focus(),e.preventDefault()},c=function(){n.children("a:first").focus(),e.preventDefault()},f=function(){var n=r.children("ul.is-dropdown-submenu");n.length&&(t._show(n),r.find("li > a:first").focus(),e.preventDefault())},d=function(){var n=r.parent("ul").parent("li");n.children("a:first").focus(),t._hide(n),e.preventDefault()},h={open:f,close:function(){t._hide(t.$element),t.$menuItems.eq(0).children("a").focus(),e.preventDefault()}};s?t._isVertical()?t._isRtl()?o().extend(h,{down:u,up:c,next:d,previous:f}):o().extend(h,{down:u,up:c,next:f,previous:d}):t._isRtl()?o().extend(h,{next:c,previous:u,down:f,up:d}):o().extend(h,{next:u,previous:c,down:f,up:d}):t._isRtl()?o().extend(h,{next:d,previous:f,down:u,up:c}):o().extend(h,{next:f,previous:d,down:u,up:c}),a.Keyboard.handleKey(e,"DropdownMenu",h)}))}},{key:"_addBodyHandler",value:function(){var t=this,e=o()(document.body);this._removeBodyHandler(),e.on("click.zf.dropdownMenu tap.zf.dropdownMenu",(function(e){o()(e.target).closest(t.$element).length||(t._hide(),t._removeBodyHandler())}))}},{key:"_removeBodyHandler",value:function(){o()(document.body).off("click.zf.dropdownMenu tap.zf.dropdownMenu")}},{key:"_show",value:function(t){var e=this.$tabs.index(this.$tabs.filter((function(e,n){return o()(n).find(t).length>0}))),n=t.parent("li.is-dropdown-submenu-parent").siblings("li.is-dropdown-submenu-parent");this._hide(n,e),t.css("visibility","hidden").addClass("js-dropdown-active").parent("li.is-dropdown-submenu-parent").addClass("is-active");var i=u.Box.ImNotTouchingYou(t,null,!0);if(!i){var r="left"===this.options.alignment?"-right":"-left",s=t.parent(".is-dropdown-submenu-parent");s.removeClass("opens".concat(r)).addClass("opens-".concat(this.options.alignment)),(i=u.Box.ImNotTouchingYou(t,null,!0))||s.removeClass("opens-".concat(this.options.alignment)).addClass("opens-inner"),this.changed=!0}t.css("visibility",""),this.options.closeOnClick&&this._addBodyHandler(),this.$element.trigger("show.zf.dropdownMenu",[t])}},{key:"_hide",value:function(t,e){var n;if((n=t&&t.length?t:void 0!==e?this.$tabs.not((function(t){return t===e})):this.$element).hasClass("is-active")||n.find(".is-active").length>0){var i=n.find("li.is-active");if(i.add(n).attr({"data-is-click":!1}).removeClass("is-active"),n.find("ul.js-dropdown-active").removeClass("js-dropdown-active"),this.changed||n.find("opens-inner").length){var o="left"===this.options.alignment?"right":"left";n.find("li.is-dropdown-submenu-parent").add(n).removeClass("opens-inner opens-".concat(this.options.alignment)).addClass("opens-".concat(o)),this.changed=!1}clearTimeout(i.data("_delay")),this._removeBodyHandler(),this.$element.trigger("hide.zf.dropdownMenu",[n])}}},{key:"_destroy",value:function(){this.$menuItems.off(".zf.dropdownMenu").removeAttr("data-is-click").removeClass("is-right-arrow is-left-arrow is-down-arrow opens-right opens-left opens-inner"),o()(document.body).off(".zf.dropdownMenu"),l.Nest.Burn(this.$element,"dropdown")}}])&&d(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),m}(r.Plugin);v.defaults={disableHover:!1,disableHoverOnTouch:!0,autoclose:!0,hoverDelay:50,clickOpen:!1,closingTime:500,alignment:"auto",closeOnClick:!0,closeOnClickInside:!0,verticalClass:"vertical",rightClass:"align-right",forceFollow:!0}},"./js/foundation.equalizer.js":function(t,e,n){n.r(e),n.d(e,{Equalizer:function(){return d}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.mediaQuery.js"),s=n("./js/foundation.util.imageLoader.js"),a=n("./js/foundation.core.utils.js");function l(t){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},l(t)}function u(t,e){for(var n=0;n0,this.isNested=this.$element.parentsUntil(document.body,"[data-equalizer]").length>0,this.isOn=!1,this._bindHandler={onResizeMeBound:this._onResizeMe.bind(this),onPostEqualizedBound:this._onPostEqualized.bind(this)};var n,i=this.$element.find("img");this.options.equalizeOn?(n=this._checkMQ(),o()(window).on("changed.zf.mediaquery",this._checkMQ.bind(this))):this._events(),(void 0!==n&&!1===n||void 0===n)&&(i.length?(0,s.onImagesLoaded)(i,this._reflow.bind(this)):this._reflow())}},{key:"_pauseEvents",value:function(){this.isOn=!1,this.$element.off({".zf.equalizer":this._bindHandler.onPostEqualizedBound,"resizeme.zf.trigger":this._bindHandler.onResizeMeBound,"mutateme.zf.trigger":this._bindHandler.onResizeMeBound})}},{key:"_onResizeMe",value:function(){this._reflow()}},{key:"_onPostEqualized",value:function(t){t.target!==this.$element[0]&&this._reflow()}},{key:"_events",value:function(){this._pauseEvents(),this.hasNested?this.$element.on("postequalized.zf.equalizer",this._bindHandler.onPostEqualizedBound):(this.$element.on("resizeme.zf.trigger",this._bindHandler.onResizeMeBound),this.$element.on("mutateme.zf.trigger",this._bindHandler.onResizeMeBound)),this.isOn=!0}},{key:"_checkMQ",value:function(){var t=!r.MediaQuery.is(this.options.equalizeOn);return t?this.isOn&&(this._pauseEvents(),this.$watched.css("height","auto")):this.isOn||this._events(),t}},{key:"_killswitch",value:function(){}},{key:"_reflow",value:function(){if(!this.options.equalizeOnStack&&this._isStacked())return this.$watched.css("height","auto"),!1;this.options.equalizeByRow?this.getHeightsByRow(this.applyHeightByRow.bind(this)):this.getHeights(this.applyHeight.bind(this))}},{key:"_isStacked",value:function(){return!this.$watched[0]||!this.$watched[1]||this.$watched[0].getBoundingClientRect().top!==this.$watched[1].getBoundingClientRect().top}},{key:"getHeights",value:function(t){for(var e=[],n=0,i=this.$watched.length;nn;if(this.scrollPos=n,n0&&"push"===this.options.transition&&(this.options.contentScroll=!1);var r=this.$element.attr("class").match(/\bin-canvas-for-(\w+)/);r&&2===r.length?this.options.inCanvasOn=r[1]:this.options.inCanvasOn&&this.$element.addClass("in-canvas-for-".concat(this.options.inCanvasOn)),this.options.inCanvasOn&&this._checkInCanvas(),this._removeContentClasses()}},{key:"_events",value:function(){var t=this;this.$element.off(".zf.trigger .zf.offCanvas").on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":this.close.bind(this),"toggle.zf.trigger":this.toggle.bind(this),"keydown.zf.offCanvas":this._handleKeyboard.bind(this)}),!0===this.options.closeOnClick&&(this.options.contentOverlay?this.$overlay:this.$content).on({"click.zf.offCanvas":this.close.bind(this)}),this.options.inCanvasOn&&o()(window).on("changed.zf.mediaquery",(function(){t._checkInCanvas()}))}},{key:"_setMQChecker",value:function(){var t=this;this.onLoadListener=(0,s.onLoad)(o()(window),(function(){l.MediaQuery.atLeast(t.options.revealOn)&&t.reveal(!0)})),o()(window).on("changed.zf.mediaquery",(function(){l.MediaQuery.atLeast(t.options.revealOn)?t.reveal(!0):t.reveal(!1)}))}},{key:"_checkInCanvas",value:function(){this.isInCanvas=l.MediaQuery.atLeast(this.options.inCanvasOn),!0===this.isInCanvas&&this.close()}},{key:"_removeContentClasses",value:function(t){"boolean"!=typeof t?this.$content.removeClass(this.contentClasses.base.join(" ")):!1===t&&this.$content.removeClass("has-reveal-".concat(this.position))}},{key:"_addContentClasses",value:function(t){this._removeContentClasses(t),"boolean"!=typeof t?this.$content.addClass("has-transition-".concat(this.options.transition," has-position-").concat(this.position)):!0===t&&this.$content.addClass("has-reveal-".concat(this.position))}},{key:"_fixStickyElements",value:function(){this.$sticky.each((function(t,e){var n=o()(e);if("fixed"===n.css("position")){var i=parseInt(n.css("top"),10);n.data("offCanvasSticky",{top:i});var r=o()(document).scrollTop()+i;n.css({top:"".concat(r,"px"),width:"100%",transition:"none"})}}))}},{key:"_unfixStickyElements",value:function(){this.$sticky.each((function(t,e){var n=o()(e),i=n.data("offCanvasSticky");"object"===c(i)&&(n.css({top:"".concat(i.top,"px"),width:"",transition:""}),n.data("offCanvasSticky",""))}))}},{key:"reveal",value:function(t){t?(this.close(),this.isRevealed=!0,this.$element.attr("aria-hidden","false"),this.$element.off("open.zf.trigger toggle.zf.trigger"),this.$element.removeClass("is-closed")):(this.isRevealed=!1,this.$element.attr("aria-hidden","true"),this.$element.off("open.zf.trigger toggle.zf.trigger").on({"open.zf.trigger":this.open.bind(this),"toggle.zf.trigger":this.toggle.bind(this)}),this.$element.addClass("is-closed")),this._addContentClasses(t)}},{key:"_stopScrolling",value:function(){return!1}},{key:"_recordScrollable",value:function(t){this.lastY=t.touches[0].pageY}},{key:"_preventDefaultAtEdges",value:function(t){var e=this,n=t.data,i=e.lastY-t.touches[0].pageY;e.lastY=t.touches[0].pageY,n._canScroll(i,e)||t.preventDefault()}},{key:"_scrollboxTouchMoved",value:function(t){var e=this,n=t.data,i=e.closest("[data-off-canvas], [data-off-canvas-scrollbox-outer]"),o=e.lastY-t.touches[0].pageY;i.lastY=e.lastY=t.touches[0].pageY,t.stopPropagation(),n._canScroll(o,e)||(n._canScroll(o,i)?i.scrollTop+=o:t.preventDefault())}},{key:"_canScroll",value:function(t,e){var n=t<0,i=t>0,o=e.scrollTop>0,r=e.scrollTop1&&this.geoSync(),this.options.accessible&&this.$wrapper.attr("tabindex",0)}},{key:"_loadBullets",value:function(){this.$bullets=this.$element.find(".".concat(this.options.boxOfBullets)).find("button")}},{key:"geoSync",value:function(){var t=this;this.timer=new a.Timer(this.$element,{duration:this.options.timerDelay,infinite:!1},(function(){t.changeSlide(!0)})),this.timer.start()}},{key:"_prepareForOrbit",value:function(){this._setWrapperHeight()}},{key:"_setWrapperHeight",value:function(t){var e,n=0,i=0,r=this;this.$slides.each((function(){e=this.getBoundingClientRect().height,o()(this).attr("data-slide",i),/mui/g.test(o()(this)[0].className)||r.$slides.filter(".is-active")[0]===r.$slides.eq(i)[0]||o()(this).css({display:"none"}),n=e>n?e:n,i++})),i===this.$slides.length&&(this.$wrapper.css({height:n}),t&&t(n))}},{key:"_setSlideHeight",value:function(t){this.$slides.each((function(){o()(this).css("max-height",t)}))}},{key:"_events",value:function(){var t=this;this.$element.off(".resizeme.zf.trigger").on({"resizeme.zf.trigger":this._prepareForOrbit.bind(this)}),this.$slides.length>1&&(this.options.swipe&&this.$slides.off("swipeleft.zf.orbit swiperight.zf.orbit").on("swipeleft.zf.orbit",(function(e){e.preventDefault(),t.changeSlide(!0)})).on("swiperight.zf.orbit",(function(e){e.preventDefault(),t.changeSlide(!1)})),this.options.autoPlay&&(this.$slides.on("click.zf.orbit",(function(){t.$element.data("clickedOn",!t.$element.data("clickedOn")),t.timer[t.$element.data("clickedOn")?"pause":"start"]()})),this.options.pauseOnHover&&this.$element.on("mouseenter.zf.orbit",(function(){t.timer.pause()})).on("mouseleave.zf.orbit",(function(){t.$element.data("clickedOn")||t.timer.start()}))),this.options.navButtons&&this.$element.find(".".concat(this.options.nextClass,", .").concat(this.options.prevClass)).attr("tabindex",0).on("click.zf.orbit touchend.zf.orbit",(function(e){e.preventDefault(),t.changeSlide(o()(this).hasClass(t.options.nextClass))})),this.options.bullets&&this.$bullets.on("click.zf.orbit touchend.zf.orbit",(function(){if(/is-active/g.test(this.className))return!1;var e=o()(this).data("slide"),n=e>t.$slides.filter(".is-active").data("slide"),i=t.$slides.eq(e);t.changeSlide(n,i,e)})),this.options.accessible&&this.$wrapper.add(this.$bullets).on("keydown.zf.orbit",(function(e){r.Keyboard.handleKey(e,"Orbit",{next:function(){t.changeSlide(!0)},previous:function(){t.changeSlide(!1)},handled:function(){o()(e.target).is(t.$bullets)&&t.$bullets.filter(".is-active").focus()}})})))}},{key:"_reset",value:function(){void 0!==this.$slides&&this.$slides.length>1&&(this.$element.off(".zf.orbit").find("*").off(".zf.orbit"),this.options.autoPlay&&this.timer.restart(),this.$slides.each((function(t){o()(t).removeClass("is-active is-active is-in").removeAttr("aria-live").hide()})),this.$slides.first().addClass("is-active").show(),this.$element.trigger("slidechange.zf.orbit",[this.$slides.first()]),this.options.bullets&&this._updateBullets(0))}},{key:"changeSlide",value:function(t,e,n){if(this.$slides){var i=this.$slides.filter(".is-active").eq(0);if(/mui/g.test(i[0].className))return!1;var o,r=this.$slides.first(),a=this.$slides.last(),l=t?"Right":"Left",u=t?"Left":"Right",c=this;(o=e||(t?this.options.infiniteWrap?i.next(".".concat(this.options.slideClass)).length?i.next(".".concat(this.options.slideClass)):r:i.next(".".concat(this.options.slideClass)):this.options.infiniteWrap?i.prev(".".concat(this.options.slideClass)).length?i.prev(".".concat(this.options.slideClass)):a:i.prev(".".concat(this.options.slideClass)))).length&&(this.$element.trigger("beforeslidechange.zf.orbit",[i,o]),this.options.bullets&&(n=n||this.$slides.index(o),this._updateBullets(n)),this.options.useMUI&&!this.$element.is(":hidden")?(s.Motion.animateIn(o.addClass("is-active"),this.options["animInFrom".concat(l)],(function(){o.css({display:"block"}).attr("aria-live","polite")})),s.Motion.animateOut(i.removeClass("is-active"),this.options["animOutTo".concat(u)],(function(){i.removeAttr("aria-live"),c.options.autoPlay&&!c.timer.isPaused&&c.timer.restart()}))):(i.removeClass("is-active is-in").removeAttr("aria-live").hide(),o.addClass("is-active is-in").attr("aria-live","polite").show(),this.options.autoPlay&&!this.timer.isPaused&&this.timer.restart()),this.$element.trigger("slidechange.zf.orbit",[o]))}}},{key:"_updateBullets",value:function(t){var e=this.$bullets.filter(".is-active"),n=this.$bullets.not(".is-active"),i=this.$bullets.eq(t);e.removeClass("is-active").blur(),i.addClass("is-active");var r=e.children("[data-slide-active-label]").last();if(!r.length){var s=e.children("span");n.toArray().map((function(t){return o()(t).children("span").length})).every((function(t){return t1?i[0]:"small",a=i.length>1?i[1]:i[0];null!==v[a]&&(t[s]=v[a])}this.rules=t}this._getAllOptions(),o().isEmptyObject(this.rules)||this._checkMediaQueries()}},{key:"_getAllOptions",value:function(){var t=this;for(var e in t.allOptions={},v)if(v.hasOwnProperty(e)){var n=v[e];try{var i=o()("
        "),r=new n.plugin(i,t.options);for(var s in r.options)if(r.options.hasOwnProperty(s)&&"zfPlugin"!==s){var a=r.options[s];t.allOptions[s]=a}r.destroy()}catch(t){console.warn("Warning: Problems getting Accordion/Tab options: ".concat(t))}}}},{key:"_events",value:function(){this._changedZfMediaQueryHandler=this._checkMediaQueries.bind(this),o()(window).on("changed.zf.mediaquery",this._changedZfMediaQueryHandler)}},{key:"_checkMediaQueries",value:function(){var t,e=this;o().each(this.rules,(function(e){r.MediaQuery.atLeast(e)&&(t=e)})),t&&(this.currentPlugin instanceof this.rules[t].plugin||(o().each(v,(function(t,n){e.$element.removeClass(n.cssClass)})),this.$element.addClass(this.rules[t].cssClass),this.currentPlugin&&(!this.currentPlugin.$element.data("zfPlugin")&&this.storezfData&&this.currentPlugin.$element.data("zfPlugin",this.storezfData),this.currentPlugin.destroy()),this._handleMarkup(this.rules[t].cssClass),this.currentRule=this.rules[t],this.currentPlugin=new this.currentRule.plugin(this.$element,this.options),this.storezfData=this.currentPlugin.$element.data("zfPlugin")))}},{key:"_handleMarkup",value:function(t){var e=this,n="accordion",i=o()("[data-tabs-content="+this.$element.attr("id")+"]");if(i.length&&(n="tabs"),n!==t){var r=e.allOptions.linkClass?e.allOptions.linkClass:"tabs-title",a=e.allOptions.panelClass?e.allOptions.panelClass:"tabs-panel";this.$element.removeAttr("role");var l=this.$element.children("."+r+",[data-accordion-item]").removeClass(r).removeClass("accordion-item").removeAttr("data-accordion-item"),u=l.children("a").removeClass("accordion-title");if("tabs"===n?(i=i.children("."+a).removeClass(a).removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby")).children("a").removeAttr("role").removeAttr("aria-controls").removeAttr("aria-selected"):i=l.children("[data-tab-content]").removeClass("accordion-content"),i.css({display:"",visibility:""}),l.css({display:"",visibility:""}),"accordion"===t)i.each((function(t,n){o()(n).appendTo(l.get(t)).addClass("accordion-content").attr("data-tab-content","").removeClass("is-active").css({height:""}),o()("[data-tabs-content="+e.$element.attr("id")+"]").after('
        ').detach(),l.addClass("accordion-item").attr("data-accordion-item",""),u.addClass("accordion-title")}));else if("tabs"===t){var c=o()("[data-tabs-content="+e.$element.attr("id")+"]"),f=o()("#tabs-placeholder-"+e.$element.attr("id"));f.length?(c=o()('
        ').insertAfter(f).attr("data-tabs-content",e.$element.attr("id")),f.remove()):c=o()('
        ').insertAfter(e.$element).attr("data-tabs-content",e.$element.attr("id")),i.each((function(t,e){var n=o()(e).appendTo(c).addClass(a),i=u.get(t).hash.slice(1),r=o()(e).attr("id")||(0,s.GetYoDigits)(6,"accordion");i!==r&&(""!==i?o()(e).attr("id",i):(i=r,o()(e).attr("id",i),o()(u.get(t)).attr("href",o()(u.get(t)).attr("href").replace("#","")+"#"+i))),o()(l.get(t)).hasClass("is-active")&&n.addClass("is-active")})),l.addClass(r)}}}},{key:"open",value:function(){var t;if(this.currentRule&&"function"==typeof this.currentRule.open)return(t=this.currentRule).open.apply(t,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"close",value:function(){var t;if(this.currentRule&&"function"==typeof this.currentRule.close)return(t=this.currentRule).close.apply(t,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"toggle",value:function(){var t;if(this.currentRule&&"function"==typeof this.currentRule.toggle)return(t=this.currentRule).toggle.apply(t,[this.currentPlugin].concat(Array.prototype.slice.call(arguments)))}},{key:"_destroy",value:function(){this.currentPlugin&&this.currentPlugin.destroy(),o()(window).off("changed.zf.mediaquery",this._changedZfMediaQueryHandler)}}],n&&c(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),u}(a.Plugin);m.defaults={}},"./js/foundation.responsiveMenu.js":function(t,e,n){n.r(e),n.d(e,{ResponsiveMenu:function(){return m}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.mediaQuery.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.core.plugin.js"),l=n("./js/foundation.dropdownMenu.js"),u=n("./js/foundation.drilldown.js"),c=n("./js/foundation.accordionMenu.js");function f(t){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},f(t)}function d(t,e){for(var n=0;n1?i[0]:"small",l=i.length>1?i[1]:i[0];null!==v[l]&&(t[a]=v[l])}this.rules=t}o().isEmptyObject(this.rules)||this._checkMediaQueries(),this.$element.attr("data-mutate",this.$element.attr("data-mutate")||(0,s.GetYoDigits)(6,"responsive-menu"))}},{key:"_events",value:function(){var t=this;o()(window).on("changed.zf.mediaquery",(function(){t._checkMediaQueries()}))}},{key:"_checkMediaQueries",value:function(){var t,e=this;o().each(this.rules,(function(e){r.MediaQuery.atLeast(e)&&(t=e)})),t&&(this.currentPlugin instanceof this.rules[t].plugin||(o().each(v,(function(t,n){e.$element.removeClass(n.cssClass)})),this.$element.addClass(this.rules[t].cssClass),this.currentPlugin&&this.currentPlugin.destroy(),this.currentPlugin=new this.rules[t].plugin(this.$element,{})))}},{key:"_destroy",value:function(){this.currentPlugin.destroy(),o()(window).off(".zf.ResponsiveMenu")}}])&&d(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),u}(a.Plugin);m.defaults={}},"./js/foundation.responsiveToggle.js":function(t,e,n){n.r(e),n.d(e,{ResponsiveToggle:function(){return f}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.mediaQuery.js"),s=n("./js/foundation.util.motion.js");function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}function l(t,e){for(var n=0;n").addClass("reveal-overlay"+t).appendTo(this.options.appendTo)}},{key:"_updatePosition",value:function(){var t,e=this.$element.outerWidth(),n=o()(window).width(),i=this.$element.outerHeight(),r=o()(window).height(),s=null;t="auto"===this.options.hOffset?parseInt((n-e)/2,10):parseInt(this.options.hOffset,10),"auto"===this.options.vOffset?s=i>r?parseInt(Math.min(100,r/10),10):parseInt((r-i)/4,10):null!==this.options.vOffset&&(s=parseInt(this.options.vOffset,10)),null!==s&&this.$element.css({top:s+"px"}),this.$overlay&&"auto"===this.options.hOffset||(this.$element.css({left:t+"px"}),this.$element.css({margin:"0px"}))}},{key:"_events",value:function(){var t=this,e=this;this.$element.on({"open.zf.trigger":this.open.bind(this),"close.zf.trigger":function(n,i){if(n.target===e.$element[0]||o()(n.target).parents("[data-closable]")[0]===i)return t.close.apply(t)},"toggle.zf.trigger":this.toggle.bind(this),"resizeme.zf.trigger":function(){e._updatePosition()}}),this.options.closeOnClick&&this.options.overlay&&this.$overlay.off(".zf.reveal").on("click.zf.dropdown tap.zf.dropdown",(function(t){t.target!==e.$element[0]&&!o().contains(e.$element[0],t.target)&&o().contains(document,t.target)&&e.close()})),this.options.deepLink&&o()(window).on("hashchange.zf.reveal:".concat(this.id),this._handleState.bind(this))}},{key:"_handleState",value:function(){window.location.hash!=="#"+this.id||this.isActive?this.close():this.open()}},{key:"_disableScroll",value:function(t){t=t||o()(window).scrollTop(),o()(document).height()>o()(window).height()&&o()("html").css("top",-t)}},{key:"_enableScroll",value:function(t){t=t||parseInt(o()("html").css("top"),10),o()(document).height()>o()(window).height()&&(o()("html").css("top",""),o()(window).scrollTop(-t))}},{key:"open",value:function(){var t=this,e="#".concat(this.id);this.options.deepLink&&window.location.hash!==e&&(window.history.pushState?this.options.updateHistory?window.history.pushState({},"",e):window.history.replaceState({},"",e):window.location.hash=e),this.$activeAnchor=o()(document.activeElement).is(this.$anchor)?o()(document.activeElement):this.$anchor,this.isActive=!0,this.$element.css({visibility:"hidden"}).show().scrollTop(0),this.options.overlay&&this.$overlay.css({visibility:"hidden"}).show(),this._updatePosition(),this.$element.hide().css({visibility:""}),this.$overlay&&(this.$overlay.css({visibility:""}).hide(),this.$element.hasClass("fast")?this.$overlay.addClass("fast"):this.$element.hasClass("slow")&&this.$overlay.addClass("slow")),this.options.multipleOpened||this.$element.trigger("closeme.zf.reveal",this.id),0===o()(".reveal:visible").length&&this._disableScroll();var n=this;this.options.animationIn?(this.options.overlay&&u.Motion.animateIn(this.$overlay,"fade-in"),u.Motion.animateIn(this.$element,this.options.animationIn,(function(){t.$element&&(t.focusableElements=a.Keyboard.findFocusable(t.$element),n.$element.attr({"aria-hidden":!1,tabindex:-1}).focus(),n._addGlobalClasses(),a.Keyboard.trapFocus(n.$element))}))):(this.options.overlay&&this.$overlay.show(0),this.$element.show(this.options.showDelay)),this.$element.attr({"aria-hidden":!1,tabindex:-1}).focus(),a.Keyboard.trapFocus(this.$element),this._addGlobalClasses(),this._addGlobalListeners(),this.$element.trigger("open.zf.reveal")}},{key:"_addGlobalClasses",value:function(){var t=function(){o()("html").toggleClass("zf-has-scroll",!!(o()(document).height()>o()(window).height()))};this.$element.on("resizeme.zf.trigger.revealScrollbarListener",(function(){return t()})),t(),o()("html").addClass("is-reveal-open")}},{key:"_removeGlobalClasses",value:function(){this.$element.off("resizeme.zf.trigger.revealScrollbarListener"),o()("html").removeClass("is-reveal-open"),o()("html").removeClass("zf-has-scroll")}},{key:"_addGlobalListeners",value:function(){var t=this;this.$element&&(this.focusableElements=a.Keyboard.findFocusable(this.$element),this.options.overlay||!this.options.closeOnClick||this.options.fullScreen||o()("body").on("click.zf.dropdown tap.zf.dropdown",(function(e){e.target!==t.$element[0]&&!o().contains(t.$element[0],e.target)&&o().contains(document,e.target)&&t.close()})),this.options.closeOnEsc&&o()(window).on("keydown.zf.reveal",(function(e){a.Keyboard.handleKey(e,"Reveal",{close:function(){t.options.closeOnEsc&&t.close()}})})))}},{key:"close",value:function(){if(!this.isActive||!this.$element.is(":visible"))return!1;var t=this;function e(){var e=parseInt(o()("html").css("top"),10);0===o()(".reveal:visible").length&&t._removeGlobalClasses(),a.Keyboard.releaseFocus(t.$element),t.$element.attr("aria-hidden",!0),0===o()(".reveal:visible").length&&t._enableScroll(e),t.$element.trigger("closed.zf.reveal")}if(this.options.animationOut?(this.options.overlay&&u.Motion.animateOut(this.$overlay,"fade-out"),u.Motion.animateOut(this.$element,this.options.animationOut,e)):(this.$element.hide(this.options.hideDelay),this.options.overlay?this.$overlay.hide(0,e):e()),this.options.closeOnEsc&&o()(window).off("keydown.zf.reveal"),!this.options.overlay&&this.options.closeOnClick&&o()("body").off("click.zf.dropdown tap.zf.dropdown"),this.$element.off("keydown.zf.reveal"),this.options.resetOnClose&&this.$element.html(this.$element.html()),this.isActive=!1,t.options.deepLink&&window.location.hash==="#".concat(this.id))if(window.history.replaceState){var n=window.location.pathname+window.location.search;this.options.updateHistory?window.history.pushState({},"",n):window.history.replaceState("",document.title,n)}else window.location.hash="";this.$activeAnchor.focus()}},{key:"toggle",value:function(){this.isActive?this.close():this.open()}},{key:"_destroy",value:function(){this.options.overlay&&(this.$element.appendTo(o()(this.options.appendTo)),this.$overlay.hide().off().remove()),this.$element.hide().off(),this.$anchor.off(".zf"),o()(window).off(".zf.reveal:".concat(this.id)),this.onLoadListener&&o()(window).off(this.onLoadListener),0===o()(".reveal:visible").length&&this._removeGlobalClasses()}}])&&h(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),g}(r.Plugin);m.defaults={animationIn:"",animationOut:"",showDelay:0,hideDelay:0,closeOnClick:!0,closeOnEsc:!0,multipleOpened:!1,vOffset:"auto",hOffset:"auto",fullScreen:!1,overlay:!0,resetOnClose:!1,deepLink:!1,updateHistory:!1,appendTo:"body",additionalOverlayClasses:""}},"./js/foundation.slider.js":function(t,e,n){n.r(e),n.d(e,{Slider:function(){return v}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.keyboard.js"),s=n("./js/foundation.util.motion.js"),a=n("./js/foundation.core.utils.js"),l=n("./js/foundation.core.plugin.js"),u=n("./js/foundation.util.touch.js"),c=n("./js/foundation.util.triggers.js");function f(t){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},f(t)}function d(t,e){for(var n=0;n1?this.inputs.eq(1):o()("#".concat(this.$handle2.attr("aria-controls"))),this.inputs[1]||(this.inputs=this.inputs.add(this.$input2)),this._setInitAttr(1)),this.setHandles(),this._events(),this.initialized=!0}},{key:"setHandles",value:function(){var t=this;this.handles[1]?this._setHandlePos(this.$handle,this.inputs.eq(0).val(),(function(){t._setHandlePos(t.$handle2,t.inputs.eq(1).val())})):this._setHandlePos(this.$handle,this.inputs.eq(0).val())}},{key:"_reflow",value:function(){this.setHandles()}},{key:"_pctOfBar",value:function(t){var e=m(t-this.options.start,this.options.end-this.options.start);switch(this.options.positionValueFunction){case"pow":e=this._logTransform(e);break;case"log":e=this._powTransform(e)}return e.toFixed(2)}},{key:"_value",value:function(t){switch(this.options.positionValueFunction){case"pow":t=this._powTransform(t);break;case"log":t=this._logTransform(t)}return this.options.vertical?parseFloat(this.options.end)+t*(this.options.start-this.options.end):(this.options.end-this.options.start)*t+parseFloat(this.options.start)}},{key:"_logTransform",value:function(t){return function(t,e){return Math.log(e)/Math.log(t)}(this.options.nonLinearBase,t*(this.options.nonLinearBase-1)+1)}},{key:"_powTransform",value:function(t){return(Math.pow(this.options.nonLinearBase,t)-1)/(this.options.nonLinearBase-1)}},{key:"_setHandlePos",value:function(t,e,n){if(!this.$element.hasClass(this.options.disabledClass)){(e=parseFloat(e))this.options.end&&(e=this.options.end);var i=this.options.doubleSided;if(i)if(0===this.handles.index(t)){var o=parseFloat(this.$handle2.attr("aria-valuenow"));e=e>=o?o-this.options.step:e}else{var r=parseFloat(this.$handle.attr("aria-valuenow"));e=e<=r?r+this.options.step:e}var a=this,l=this.options.vertical,u=l?"height":"width",c=l?"top":"left",f=t[0].getBoundingClientRect()[u],d=this.$element[0].getBoundingClientRect()[u],h=this._pctOfBar(e),p=(100*m((d-f)*h,d)).toFixed(this.options.decimal);e=parseFloat(e.toFixed(this.options.decimal));var v={};if(this._setValues(t,e),i){var g,y=0===this.handles.index(t),b=Math.floor(100*m(f,d));if(y)v[c]="".concat(p,"%"),g=parseFloat(this.$handle2[0].style[c])-p+b,n&&"function"==typeof n&&n();else{var w=parseFloat(this.$handle[0].style[c]);g=p-(isNaN(w)?(this.options.initialStart-this.options.start)/((this.options.end-this.options.start)/100):w)+b}v["min-".concat(u)]="".concat(g,"%")}var k=this.$element.data("dragging")?1e3/60:this.options.moveTime;(0,s.Move)(k,t,(function(){isNaN(p)?t.css(c,"".concat(100*h,"%")):t.css(c,"".concat(p,"%")),a.options.doubleSided?a.$fill.css(v):a.$fill.css(u,"".concat(100*h,"%"))})),this.initialized&&(this.$element.one("finished.zf.animate",(function(){a.$element.trigger("moved.zf.slider",[t])})),clearTimeout(a.timeout),a.timeout=setTimeout((function(){a.$element.trigger("changed.zf.slider",[t])}),a.options.changedDelay))}}},{key:"_setInitAttr",value:function(t){var e=0===t?this.options.initialStart:this.options.initialEnd,n=this.inputs.eq(t).attr("id")||(0,a.GetYoDigits)(6,"slider");this.inputs.eq(t).attr({id:n,max:this.options.end,min:this.options.start,step:this.options.step}),this.inputs.eq(t).val(e),this.handles.eq(t).attr({role:"slider","aria-controls":n,"aria-valuemax":this.options.end,"aria-valuemin":this.options.start,"aria-valuenow":e,"aria-orientation":this.options.vertical?"vertical":"horizontal",tabindex:0})}},{key:"_setValues",value:function(t,e){var n=this.options.doubleSided?this.handles.index(t):0;this.inputs.eq(n).val(e),t.attr("aria-valuenow",e)}},{key:"_handleEvent",value:function(t,e,n){var i;if(n)i=this._adjustValue(null,n);else{t.preventDefault();var r=this.options.vertical,s=r?"height":"width",l=r?"top":"left",u=r?t.pageY:t.pageX,c=this.$element[0].getBoundingClientRect()[s],f=r?o()(window).scrollTop():o()(window).scrollLeft(),d=this.$element.offset()[l];t.clientY===t.pageY&&(u+=f);var h,p=u-d,v=m(h=p<0?0:p>c?c:p,c);i=this._value(v),(0,a.rtl)()&&!this.options.vertical&&(i=this.options.end-i),i=this._adjustValue(null,i),e||(e=g(this.$handle,l,h,s)<=g(this.$handle2,l,h,s)?this.$handle:this.$handle2)}this._setHandlePos(e,i)}},{key:"_adjustValue",value:function(t,e){var n,i,o,r=this.options.step,s=parseFloat(r/2);return 0===(i=(n=t?parseFloat(t.attr("aria-valuenow")):e)>=0?n%r:r+n%r)?n:n=n>=(o=n-i)+s?o+r:o}},{key:"_events",value:function(){this._eventsForHandle(this.$handle),this.handles[1]&&this._eventsForHandle(this.$handle2)}},{key:"_eventsForHandle",value:function(t){var e,n=this,i=function(t){var e=n.inputs.index(o()(this));n._handleEvent(t,n.handles.eq(e),o()(this).val())};if(this.inputs.off("keyup.zf.slider").on("keyup.zf.slider",(function(t){13===t.keyCode&&i.call(this,t)})),this.inputs.off("change.zf.slider").on("change.zf.slider",i),this.options.clickSelect&&this.$element.off("click.zf.slider").on("click.zf.slider",(function(t){if(n.$element.data("dragging"))return!1;o()(t.target).is("[data-slider-handle]")||(n.options.doubleSided?n._handleEvent(t):n._handleEvent(t,n.$handle))})),this.options.draggable){this.handles.addTouch();var s=o()("body");t.off("mousedown.zf.slider").on("mousedown.zf.slider",(function(i){t.addClass("is-dragging"),n.$fill.addClass("is-dragging"),n.$element.data("dragging",!0),e=o()(i.currentTarget),s.on("mousemove.zf.slider",(function(t){t.preventDefault(),n._handleEvent(t,e)})).on("mouseup.zf.slider",(function(i){n._handleEvent(i,e),t.removeClass("is-dragging"),n.$fill.removeClass("is-dragging"),n.$element.data("dragging",!1),s.off("mousemove.zf.slider mouseup.zf.slider")}))})).on("selectstart.zf.slider touchmove.zf.slider",(function(t){t.preventDefault()}))}t.off("keydown.zf.slider").on("keydown.zf.slider",(function(e){var i,s=o()(this),a=(n.options.doubleSided&&n.handles.index(s),parseFloat(t.attr("aria-valuenow")));r.Keyboard.handleKey(e,"Slider",{decrease:function(){i=a-n.options.step},increase:function(){i=a+n.options.step},decreaseFast:function(){i=a-10*n.options.step},increaseFast:function(){i=a+10*n.options.step},min:function(){i=n.options.start},max:function(){i=n.options.end},handled:function(){e.preventDefault(),n._setHandlePos(s,i)}})}))}},{key:"_destroy",value:function(){this.handles.off(".zf.slider"),this.inputs.off(".zf.slider"),this.$element.off(".zf.slider"),clearTimeout(this.timeout)}}])&&d(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),y}(l.Plugin);function m(t,e){return t/e}function g(t,e,n,i){return Math.abs(t.position()[e]+t[i]()/2-n)}v.defaults={start:0,end:100,step:1,initialStart:0,initialEnd:100,binding:!1,clickSelect:!0,vertical:!1,draggable:!0,disabled:!1,doubleSided:!1,decimal:2,moveTime:200,disabledClass:"disabled",invertVertical:!1,changedDelay:500,nonLinearBase:5,positionValueFunction:"linear"}},"./js/foundation.smoothScroll.js":function(t,e,n){n.r(e),n.d(e,{SmoothScroll:function(){return c}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.utils.js");function s(t){return s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},s(t)}function a(t,e){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:h.defaults,n=arguments.length>2?arguments[2]:void 0,i=o()(t);if(!i.length)return!1;var r=Math.round(i.offset().top-e.threshold/2-e.offset);o()("html, body").stop(!0).animate({scrollTop:r},e.animationDuration,e.animationEasing,(function(){"function"==typeof n&&n()}))}}],(n=[{key:"_setup",value:function(t,e){this.$element=t,this.options=o().extend({},h.defaults,this.$element.data(),e),this.className="SmoothScroll",this._init()}},{key:"_init",value:function(){var t=this.$element[0].id||(0,r.GetYoDigits)(6,"smooth-scroll");this.$element.attr({id:t}),this._events()}},{key:"_events",value:function(){this._linkClickListener=this._handleLinkClick.bind(this),this.$element.on("click.zf.smoothScroll",this._linkClickListener),this.$element.on("click.zf.smoothScroll",'a[href^="#"]',this._linkClickListener)}},{key:"_handleLinkClick",value:function(t){var e=this;if(o()(t.currentTarget).is('a[href^="#"]')){var n=t.currentTarget.getAttribute("href");this._inTransition=!0,h.scrollToLoc(n,this.options,(function(){e._inTransition=!1})),t.preventDefault()}}},{key:"_destroy",value:function(){this.$element.off("click.zf.smoothScroll",this._linkClickListener),this.$element.off("click.zf.smoothScroll",'a[href^="#"]',this._linkClickListener)}}])&&a(e.prototype,n),i&&a(e,i),Object.defineProperty(e,"prototype",{writable:!1}),h}(n("./js/foundation.core.plugin.js").Plugin);c.defaults={animationDuration:500,animationEasing:"linear",threshold:50,offset:0}},"./js/foundation.sticky.js":function(t,e,n){n.r(e),n.d(e,{Sticky:function(){return h}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.plugin.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.util.mediaQuery.js"),l=n("./js/foundation.util.triggers.js");function u(t){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}function c(t,e){for(var n=0;n=n.topPoint))})),n._events(e.split("-").reverse().join("-"))}))}},{key:"_parsePoints",value:function(){for(var t=[""===this.options.topAnchor?1:this.options.topAnchor,""===this.options.btmAnchor?document.documentElement.scrollHeight:this.options.btmAnchor],e={},n=0,i=t.length;n=this.topPoint?e<=this.bottomPoint?this.isStuck||this._setSticky():this.isStuck&&this._removeSticky(!1):this.isStuck&&this._removeSticky(!0)}},{key:"_setSticky",value:function(){var t=this,e=this.options.stickTo,n="top"===e?"marginTop":"marginBottom",i="top"===e?"bottom":"top",o={};o[n]="".concat(this.options[n],"em"),o[e]=0,o[i]="auto",this.isStuck=!0,this.$element.removeClass("is-anchored is-at-".concat(i)).addClass("is-stuck is-at-".concat(e)).css(o).trigger("sticky.zf.stuckto:".concat(e)),this.$element.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd",(function(){t._setSizes()}))}},{key:"_removeSticky",value:function(t){var e=this.options.stickTo,n="top"===e,i={},o=(this.points?this.points[1]-this.points[0]:this.anchorHeight)-this.elemHeight,r=t?"top":"bottom";i[n?"marginTop":"marginBottom"]=0,i.bottom="auto",i.top=t?0:o,this.isStuck=!1,this.$element.removeClass("is-stuck is-at-".concat(e)).addClass("is-anchored is-at-".concat(r)).css(i).trigger("sticky.zf.unstuckfrom:".concat(r))}},{key:"_setSizes",value:function(t){this.canStick=a.MediaQuery.is(this.options.stickyOn),this.canStick||t&&"function"==typeof t&&t();var e=this.$container[0].getBoundingClientRect().width,n=window.getComputedStyle(this.$container[0]),i=parseInt(n["padding-left"],10),o=parseInt(n["padding-right"],10);if(this.$anchor&&this.$anchor.length?this.anchorHeight=this.$anchor[0].getBoundingClientRect().height:this._parsePoints(),this.$element.css({"max-width":"".concat(e-i-o,"px")}),this.options.dynamicHeight||!this.containerHeight){var r=this.$element[0].getBoundingClientRect().height||this.containerHeight;r="none"===this.$element.css("display")?0:r,this.$container.css("height",r),this.containerHeight=r}if(this.elemHeight=this.containerHeight,!this.isStuck&&this.$element.hasClass("is-at-bottom")){var s=(this.points?this.points[1]-this.$container.offset().top:this.anchorHeight)-this.elemHeight;this.$element.css("top",s)}this._setBreakPoints(this.containerHeight,(function(){t&&"function"==typeof t&&t()}))}},{key:"_setBreakPoints",value:function(t,e){if(!this.canStick){if(!e||"function"!=typeof e)return!1;e()}var n=p(this.options.marginTop),i=p(this.options.marginBottom),o=this.points?this.points[0]:this.$anchor.offset().top,r=this.points?this.points[1]:o+this.anchorHeight,s=window.innerHeight;"top"===this.options.stickTo?(o-=n,r-=t+n):"bottom"===this.options.stickTo&&(o-=s-(t+i),r-=s-i),this.topPoint=o,this.bottomPoint=r,e&&"function"==typeof e&&e()}},{key:"_destroy",value:function(){this._removeSticky(!0),this.$element.removeClass("".concat(this.options.stickyClass," is-anchored is-at-top")).css({height:"",top:"",bottom:"","max-width":""}).off("resizeme.zf.trigger").off("mutateme.zf.trigger"),this.$anchor&&this.$anchor.length&&this.$anchor.off("change.zf.sticky"),this.scrollListener&&o()(window).off(this.scrollListener),this.onLoadListener&&o()(window).off(this.onLoadListener),this.wasWrapped?this.$element.unwrap():this.$container.removeClass(this.options.containerClass).css({height:""})}}])&&c(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),v}(r.Plugin);function p(t){return parseInt(window.getComputedStyle(document.body,null).fontSize,10)*t}h.defaults={container:"
        ",stickTo:"top",anchor:"",topAnchor:"",btmAnchor:"",marginTop:1,marginBottom:1,stickyOn:"medium",stickyClass:"sticky",containerClass:"sticky-container",dynamicHeight:!0,checkEvery:-1}},"./js/foundation.tabs.js":function(t,e,n){n.r(e),n.d(e,{Tabs:function(){return h}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.plugin.js"),s=n("./js/foundation.core.utils.js"),a=n("./js/foundation.util.keyboard.js"),l=n("./js/foundation.util.imageLoader.js");function u(t){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}function c(t,e){for(var n=0;n=0?e.slice(1):e,i=n&&o()("#".concat(n)),r=e&&t.$element.find('[href$="'.concat(e,'"],[data-tabs-target="').concat(n,'"]')).first();if(i.length&&r.length){if(i&&i.length&&r&&r.length?t.selectTab(i,!0):t._collapse(),t.options.deepLinkSmudge){var s=t.$element.offset();o()("html, body").animate({scrollTop:s.top-t.options.deepLinkSmudgeOffset},t.options.deepLinkSmudgeDelay)}t.$element.trigger("deeplink.zf.tabs",[r,i])}},this.options.deepLink&&this._checkDeepLink(),this._events(),this._isInitializing=!1}},{key:"_events",value:function(){this._addKeyHandler(),this._addClickHandler(),this._setHeightMqHandler=null,this.options.matchHeight&&(this._setHeightMqHandler=this._setHeight.bind(this),o()(window).on("changed.zf.mediaquery",this._setHeightMqHandler)),this.options.deepLink&&o()(window).on("hashchange",this._checkDeepLink)}},{key:"_addClickHandler",value:function(){var t=this;this.$element.off("click.zf.tabs").on("click.zf.tabs",".".concat(this.options.linkClass),(function(e){e.preventDefault(),t._handleTabChange(o()(this))}))}},{key:"_addKeyHandler",value:function(){var t=this;this.$tabTitles.off("keydown.zf.tabs").on("keydown.zf.tabs",(function(e){if(9!==e.which){var n,i,r=o()(this),s=r.parent("ul").children("li");s.each((function(e){o()(this).is(r)&&(t.options.wrapOnKeys?(n=0===e?s.last():s.eq(e-1),i=e===s.length-1?s.first():s.eq(e+1)):(n=s.eq(Math.max(0,e-1)),i=s.eq(Math.min(e+1,s.length-1))))})),a.Keyboard.handleKey(e,"Tabs",{open:function(){r.find('[role="tab"]').focus(),t._handleTabChange(r)},previous:function(){n.find('[role="tab"]').focus(),t._handleTabChange(n)},next:function(){i.find('[role="tab"]').focus(),t._handleTabChange(i)},handled:function(){e.preventDefault()}})}}))}},{key:"_handleTabChange",value:function(t,e){if(t.hasClass("".concat(this.options.linkActiveClass)))this.options.activeCollapse&&this._collapse();else{var n=this.$element.find(".".concat(this.options.linkClass,".").concat(this.options.linkActiveClass)),i=t.find('[role="tab"]'),o=i.attr("data-tabs-target"),r=o&&o.length?"#".concat(o):i[0].hash,s=this.$tabContent.find(r);this._collapseTab(n),this._openTab(t),this.options.deepLink&&!e&&(this.options.updateHistory?history.pushState({},"",r):history.replaceState({},"",r)),this.$element.trigger("change.zf.tabs",[t,s]),s.find("[data-mutate]").trigger("mutateme.zf.trigger")}}},{key:"_openTab",value:function(t){var e=t.find('[role="tab"]'),n=e.attr("data-tabs-target")||e[0].hash.slice(1),i=this.$tabContent.find("#".concat(n));t.addClass("".concat(this.options.linkActiveClass)),e.attr({"aria-selected":"true",tabindex:"0"}),i.addClass("".concat(this.options.panelActiveClass)).removeAttr("aria-hidden")}},{key:"_collapseTab",value:function(t){var e=t.removeClass("".concat(this.options.linkActiveClass)).find('[role="tab"]').attr({"aria-selected":"false",tabindex:-1});o()("#".concat(e.attr("aria-controls"))).removeClass("".concat(this.options.panelActiveClass)).attr({"aria-hidden":"true"})}},{key:"_collapse",value:function(){var t=this.$element.find(".".concat(this.options.linkClass,".").concat(this.options.linkActiveClass));t.length&&(this._collapseTab(t),this.$element.trigger("collapse.zf.tabs",[t]))}},{key:"selectTab",value:function(t,e){var n,i;(n="object"===u(t)?t[0].id:t).indexOf("#")<0?i="#".concat(n):(i=n,n=n.slice(1));var o=this.$tabTitles.has('[href$="'.concat(i,'"],[data-tabs-target="').concat(n,'"]')).first();this._handleTabChange(o,e)}},{key:"_setHeight",value:function(){var t=0,e=this;this.$tabContent&&this.$tabContent.find(".".concat(this.options.panelClass)).css("min-height","").each((function(){var n=o()(this),i=n.hasClass("".concat(e.options.panelActiveClass));i||n.css({visibility:"hidden",display:"block"});var r=this.getBoundingClientRect().height;i||n.css({visibility:"",display:""}),t=r>t?r:t})).css("min-height","".concat(t,"px"))}},{key:"_destroy",value:function(){this.$element.find(".".concat(this.options.linkClass)).off(".zf.tabs").hide().end().find(".".concat(this.options.panelClass)).hide(),this.options.matchHeight&&null!=this._setHeightMqHandler&&o()(window).off("changed.zf.mediaquery",this._setHeightMqHandler),this.options.deepLink&&o()(window).off("hashchange",this._checkDeepLink),this.onLoadListener&&o()(window).off(this.onLoadListener)}}])&&c(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),p}(r.Plugin);h.defaults={deepLink:!1,deepLinkSmudge:!1,deepLinkSmudgeDelay:300,deepLinkSmudgeOffset:0,updateHistory:!1,autoFocus:!1,wrapOnKeys:!0,matchHeight:!1,activeCollapse:!1,linkClass:"tabs-title",linkActiveClass:"is-active",panelClass:"tabs-panel",panelActiveClass:"is-active"}},"./js/foundation.toggler.js":function(t,e,n){n.r(e),n.d(e,{Toggler:function(){return h}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.util.motion.js"),s=n("./js/foundation.core.plugin.js"),a=n("./js/foundation.core.utils.js"),l=n("./js/foundation.util.triggers.js");function u(t){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}function c(t,e){for(var n=0;n").addClass(e).attr({role:"tooltip","aria-hidden":!0,"data-is-active":!1,"data-is-focus":!1,id:t})}},{key:"_setPosition",value:function(){c(d(v.prototype),"_setPosition",this).call(this,this.$element,this.template)}},{key:"show",value:function(){if("all"!==this.options.showOn&&!s.MediaQuery.is(this.options.showOn))return!1;this.template.css("visibility","hidden").show(),this._setPosition(),this.template.removeClass("top bottom left right").addClass(this.position),this.template.removeClass("align-top align-bottom align-left align-right align-center").addClass("align-"+this.alignment),this.$element.trigger("closeme.zf.tooltip",this.template.attr("id")),this.template.attr({"data-is-active":!0,"aria-hidden":!1}),this.isActive=!0,this.template.stop().hide().css("visibility","").fadeIn(this.options.fadeInDuration,(function(){})),this.$element.trigger("show.zf.tooltip")}},{key:"hide",value:function(){var t=this;this.template.stop().attr({"aria-hidden":!0,"data-is-active":!1}).fadeOut(this.options.fadeOutDuration,(function(){t.isActive=!1,t.isClick=!1})),this.$element.trigger("hide.zf.tooltip")}},{key:"_events",value:function(){var t=this,e="ontouchstart"in window||void 0!==window.ontouchstart,n=!1;e&&this.options.disableForTouch||(this.options.disableHover||this.$element.on("mouseenter.zf.tooltip",(function(){t.isActive||(t.timeout=setTimeout((function(){t.show()}),t.options.hoverDelay))})).on("mouseleave.zf.tooltip",(0,r.ignoreMousedisappear)((function(){clearTimeout(t.timeout),(!n||t.isClick&&!t.options.clickOpen)&&t.hide()}))),e&&this.$element.on("tap.zf.tooltip touchend.zf.tooltip",(function(){t.isActive?t.hide():t.show()})),this.options.clickOpen?this.$element.on("mousedown.zf.tooltip",(function(){t.isClick||(t.isClick=!0,!t.options.disableHover&&t.$element.attr("tabindex")||t.isActive||t.show())})):this.$element.on("mousedown.zf.tooltip",(function(){t.isClick=!0})),this.$element.on({"close.zf.trigger":this.hide.bind(this)}),this.$element.on("focus.zf.tooltip",(function(){if(n=!0,t.isClick)return t.options.clickOpen||(n=!1),!1;t.show()})).on("focusout.zf.tooltip",(function(){n=!1,t.isClick=!1,t.hide()})).on("resizeme.zf.trigger",(function(){t.isActive&&t._setPosition()})))}},{key:"toggle",value:function(){this.isActive?this.hide():this.show()}},{key:"_destroy",value:function(){this.$element.attr("title",this.template.text()).off(".zf.trigger .zf.tooltip").removeClass(this.options.triggerClass).removeClass("top right left bottom").removeAttr("aria-describedby data-disable-hover data-resize data-toggle data-tooltip data-yeti-box"),this.template.remove()}}])&&u(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),v}(n("./js/foundation.positionable.js").Positionable);h.defaults={hoverDelay:200,fadeInDuration:150,fadeOutDuration:150,disableHover:!1,disableForTouch:!1,templateClasses:"",tooltipClass:"tooltip",triggerClass:"has-tip",showOn:"small",template:"",tipText:"",touchCloseText:"Tap to close.",clickOpen:!0,position:"auto",alignment:"auto",allowOverlap:!1,allowBottomOverlap:!1,vOffset:0,hOffset:0,tooltipHeight:14,tooltipWidth:12,allowHtml:!1}},"./js/foundation.util.box.js":function(t,e,n){n.r(e),n.d(e,{Box:function(){return i}});var i={ImNotTouchingYou:function(t,e,n,i,r){return 0===o(t,e,n,i,r)},OverlapArea:o,GetDimensions:r,GetExplicitOffsets:function(t,e,n,i,o,s,a){var l,u,c=r(t),f=e?r(e):null;if(null!==f){switch(n){case"top":l=f.offset.top-(c.height+o);break;case"bottom":l=f.offset.top+f.height+o;break;case"left":u=f.offset.left-(c.width+s);break;case"right":u=f.offset.left+f.width+s}switch(n){case"top":case"bottom":switch(i){case"left":u=f.offset.left+s;break;case"right":u=f.offset.left-c.width+f.width-s;break;case"center":u=a?s:f.offset.left+f.width/2-c.width/2+s}break;case"right":case"left":switch(i){case"bottom":l=f.offset.top-o+f.height-c.height;break;case"top":l=f.offset.top+o;break;case"center":l=f.offset.top+o+f.height/2-c.height/2}}}return{top:l,left:u}}};function o(t,e,n,i,o){var s,a,l,u,c=r(t);if(e){var f=r(e);a=f.height+f.offset.top-(c.offset.top+c.height),s=c.offset.top-f.offset.top,l=c.offset.left-f.offset.left,u=f.width+f.offset.left-(c.offset.left+c.width)}else a=c.windowDims.height+c.windowDims.offset.top-(c.offset.top+c.height),s=c.offset.top-c.windowDims.offset.top,l=c.offset.left-c.windowDims.offset.left,u=c.windowDims.width-(c.offset.left+c.width);return a=o?0:Math.min(a,0),s=Math.min(s,0),l=Math.min(l,0),u=Math.min(u,0),n?l+u:i?s+a:Math.sqrt(s*s+a*a+l*l+u*u)}function r(t){if((t=t.length?t[0]:t)===window||t===document)throw new Error("I'm sorry, Dave. I'm afraid I can't do that.");var e=t.getBoundingClientRect(),n=t.parentNode.getBoundingClientRect(),i=document.body.getBoundingClientRect(),o=window.pageYOffset,r=window.pageXOffset;return{width:e.width,height:e.height,offset:{top:e.top+o,left:e.left+r},parentDims:{width:n.width,height:n.height,offset:{top:n.top+o,left:n.left+r}},windowDims:{width:i.width,height:i.height,offset:{top:o,left:r}}}}},"./js/foundation.util.imageLoader.js":function(t,e,n){n.r(e),n.d(e,{onImagesLoaded:function(){return r}});var i=n("jquery"),o=n.n(i);function r(t,e){var n=t.length;function i(){0==--n&&e()}0===n&&e(),t.each((function(){if(this.complete&&void 0!==this.naturalWidth)i();else{var t=new Image,e="load.zf.images error.zf.images";o()(t).one(e,(function t(){o()(this).off(e,t),i()})),t.src=o()(this).attr("src")}}))}},"./js/foundation.util.keyboard.js":function(t,e,n){n.r(e),n.d(e,{Keyboard:function(){return c}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.utils.js"),s={9:"TAB",13:"ENTER",27:"ESCAPE",32:"SPACE",35:"END",36:"HOME",37:"ARROW_LEFT",38:"ARROW_UP",39:"ARROW_RIGHT",40:"ARROW_DOWN"},a={};function l(t){return!!t&&t.find("a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]").filter((function(){return!(!o()(this).is(":visible")||o()(this).attr("tabindex")<0)})).sort((function(t,e){if(o()(t).attr("tabindex")===o()(e).attr("tabindex"))return 0;var n=parseInt(o()(t).attr("tabindex"),10),i=parseInt(o()(e).attr("tabindex"),10);return void 0===o()(t).attr("tabindex")&&i>0?1:void 0===o()(e).attr("tabindex")&&n>0?-1:0===n&&i>0?1:0===i&&n>0||ni?1:void 0}))}function u(t){var e=s[t.which||t.keyCode]||String.fromCharCode(t.which).toUpperCase();return e=e.replace(/\W+/,""),t.shiftKey&&(e="SHIFT_".concat(e)),t.ctrlKey&&(e="CTRL_".concat(e)),t.altKey&&(e="ALT_".concat(e)),e.replace(/_$/,"")}var c={keys:function(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[t[n]]=t[n]);return e}(s),parseKey:u,handleKey:function(t,e,n){var i,s=a[e],l=this.parseKey(t);if(!s)return console.warn("Component not defined!");if(!0!==t.zfIsKeyHandled)if((i=n[(void 0===s.ltr?s:(0,r.rtl)()?o().extend({},s.ltr,s.rtl):o().extend({},s.rtl,s.ltr))[l]])&&"function"==typeof i){var u=i.apply();t.zfIsKeyHandled=!0,(n.handled||"function"==typeof n.handled)&&n.handled(u)}else(n.unhandled||"function"==typeof n.unhandled)&&n.unhandled()},findFocusable:l,register:function(t,e){a[t]=e},trapFocus:function(t){var e=l(t),n=e.eq(0),i=e.eq(-1);t.on("keydown.zf.trapfocus",(function(t){t.target===i[0]&&"TAB"===u(t)?(t.preventDefault(),n.focus()):t.target===n[0]&&"SHIFT_TAB"===u(t)&&(t.preventDefault(),i.focus())}))},releaseFocus:function(t){t.off("keydown.zf.trapfocus")}}},"./js/foundation.util.mediaQuery.js":function(t,e,n){n.r(e),n.d(e,{MediaQuery:function(){return a}});var i=n("jquery"),o=n.n(i);function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function s(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,i=new Array(e);n').appendTo(document.head);var t,e,n,i=o()(".foundation-mq").css("font-family");for(var r in n=void 0,n={},t="string"!=typeof(e=i)?n:(e=e.trim().slice(1,-1))?(n=e.split("&").reduce((function(t,e){var n=e.replace(/\+/g," ").split("="),i=n[0],o=n[1];return i=decodeURIComponent(i),o=void 0===o?null:decodeURIComponent(o),t.hasOwnProperty(i)?Array.isArray(t[i])?t[i].push(o):t[i]=[t[i],o]:t[i]=o,t}),{}),n):n,this.queries=[],t)t.hasOwnProperty(r)&&this.queries.push({name:r,value:"only screen and (min-width: ".concat(t[r],")")});this.current=this._getCurrentSize(),this._watcher()},_reInit:function(){this.isInitialized=!1,this._init()},atLeast:function(t){var e=this.get(t);return!!e&&window.matchMedia(e).matches},only:function(t){return t===this._getCurrentSize()},upTo:function(t){var e=this.next(t);return!e||!this.atLeast(e)},is:function(t){var e,n,i=(e=t.trim().split(" ").filter((function(t){return!!t.length})),n=2,function(t){if(Array.isArray(t))return t}(e)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){var i,o,r,s,a=[],l=!0,u=!1;try{if(r=(n=n.call(t)).next,0===e){if(Object(n)!==n)return;l=!1}else for(;!(l=(i=r.call(n)).done)&&(a.push(i.value),a.length!==e);l=!0);}catch(t){u=!0,o=t}finally{try{if(!l&&null!=n.return&&(s=n.return(),Object(s)!==s))return}finally{if(u)throw o}}return a}}(e,n)||function(t,e){if(t){if("string"==typeof t)return s(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(t,e):void 0}}(e,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),o=i[0],r=i[1],a=void 0===r?"":r;if("only"===a)return this.only(o);if(!a||"up"===a)return this.atLeast(o);if("down"===a)return this.upTo(o);throw new Error('\n Invalid breakpoint passed to MediaQuery.is().\n Expected a breakpoint name formatted like " ", got "'.concat(t,'".\n '))},get:function(t){for(var e in this.queries)if(this.queries.hasOwnProperty(e)){var n=this.queries[e];if(t===n.name)return n.value}return null},next:function(t){var e=this,n=this.queries.findIndex((function(n){return e._getQueryName(n)===t}));if(-1===n)throw new Error('\n Unknown breakpoint "'.concat(t,'" passed to MediaQuery.next().\n Ensure it is present in your Sass "$breakpoints" setting.\n '));var i=this.queries[n+1];return i?i.name:null},_getQueryName:function(t){if("string"==typeof t)return t;if("object"===r(t))return t.name;throw new TypeError('\n Invalid value passed to MediaQuery._getQueryName().\n Expected a breakpoint name (String) or a breakpoint query (Object), got "'.concat(t,'" (').concat(r(t),")\n "))},_getCurrentSize:function(){for(var t,e=0;e1&&void 0!==arguments[1]?arguments[1]:"zf";t.attr("role","menubar"),t.find("a").attr({role:"menuitem"});var n=t.find("li").attr({role:"none"}),i="is-".concat(e,"-submenu"),r="".concat(i,"-item"),s="is-".concat(e,"-submenu-parent"),a="accordion"!==e;n.each((function(){var t=o()(this),n=t.children("ul");if(n.length){if(t.addClass(s),a){var l=t.children("a:first");l.attr({"aria-haspopup":!0,"aria-label":l.attr("aria-label")||l.text()}),"drilldown"===e&&t.attr({"aria-expanded":!1})}n.addClass("submenu ".concat(i)).attr({"data-submenu":"",role:"menubar"}),"drilldown"===e&&n.attr({"aria-hidden":!0})}t.parent("[data-submenu]").length&&t.addClass("is-submenu-item ".concat(r))}))},Burn:function(t,e){var n="is-".concat(e,"-submenu"),i="".concat(n,"-item"),o="is-".concat(e,"-submenu-parent");t.find(">li, > li > ul, .menu, .menu > li, [data-submenu] > li").removeClass("".concat(n," ").concat(i," ").concat(o," is-submenu-item submenu is-active")).removeAttr("data-submenu").css("display","")}}},"./js/foundation.util.timer.js":function(t,e,n){function i(t,e,n){var i,o,r=this,s=e.duration,a=Object.keys(t.data())[0]||"timer",l=-1;this.isPaused=!1,this.restart=function(){l=-1,clearTimeout(o),this.start()},this.start=function(){this.isPaused=!1,clearTimeout(o),l=l<=0?s:l,t.data("paused",!1),i=Date.now(),o=setTimeout((function(){e.infinite&&r.restart(),n&&"function"==typeof n&&n()}),l),t.trigger("timerstart.zf.".concat(a))},this.pause=function(){this.isPaused=!0,clearTimeout(o),t.data("paused",!0);var e=Date.now();l-=e-i,t.trigger("timerpaused.zf.".concat(a))}}n.r(e),n.d(e,{Timer:function(){return i}})},"./js/foundation.util.touch.js":function(t,e,n){n.r(e),n.d(e,{Touch:function(){return f}});var i=n("jquery"),o=n.n(i);function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function s(t,e){for(var n=0;n=o().spotSwipe.moveThreshold&&u<=o().spotSwipe.timeThreshold&&(e=i>0?"left":"right"),e&&(t.preventDefault(),p.apply(this,arguments),o()(this).trigger(o().Event("swipe",Object.assign({},t)),e).trigger(o().Event("swipe".concat(e),Object.assign({},t))))}}function m(t){1===t.touches.length&&(a=t.touches[0].pageX,c=t,d=!0,h=!1,l=(new Date).getTime(),this.addEventListener("touchmove",v,{passive:!0===o().spotSwipe.preventDefault}),this.addEventListener("touchend",p,!1))}function g(){this.addEventListener&&this.addEventListener("touchstart",m,{passive:!0})}var y=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.version="1.0.0",this.enabled="ontouchstart"in document.documentElement,this.preventDefault=!1,this.moveThreshold=75,this.timeThreshold=200,this._init()}var e,n;return e=t,(n=[{key:"_init",value:function(){o().event.special.swipe={setup:g},o().event.special.tap={setup:g},o().each(["left","up","down","right"],(function(){o().event.special["swipe".concat(this)]={setup:function(){o()(this).on("swipe",o().noop)}}}))}}])&&s(e.prototype,n),Object.defineProperty(e,"prototype",{writable:!1}),t}();f.setupSpotSwipe=function(){o().spotSwipe=new y(o())},f.setupTouchHandler=function(){o().fn.addTouch=function(){this.each((function(e,n){o()(n).bind("touchstart touchmove touchend touchcancel",(function(e){t(e)}))}));var t=function(t){var e,n=t.changedTouches[0],i={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup"}[t.type];"MouseEvent"in window&&"function"==typeof window.MouseEvent?e=new window.MouseEvent(i,{bubbles:!0,cancelable:!0,screenX:n.screenX,screenY:n.screenY,clientX:n.clientX,clientY:n.clientY}):(e=document.createEvent("MouseEvent")).initMouseEvent(i,!0,!0,window,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(e)}}},f.init=function(){void 0===o().spotSwipe&&(f.setupSpotSwipe(o()),f.setupTouchHandler(o()))}},"./js/foundation.util.triggers.js":function(t,e,n){n.r(e),n.d(e,{Triggers:function(){return c}});var i=n("jquery"),o=n.n(i),r=n("./js/foundation.core.utils.js"),s=n("./js/foundation.util.motion.js");function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}var l=function(){for(var t=["WebKit","Moz","O","Ms",""],e=0;e0&&e-1 in t)}function O(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()}x.fn=x.prototype={jquery:_,constructor:x,length:0,toArray:function(){return a.call(this)},get:function(t){return null==t?a.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=x.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return x.each(this,t)},map:function(t){return this.pushStack(x.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return this.pushStack(a.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(x.grep(this,(function(t,e){return(e+1)%2})))},odd:function(){return this.pushStack(x.grep(this,(function(t,e){return e%2})))},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n+~]|"+z+")"+z+"*"),F=new RegExp(z+"|>"),N=new RegExp(M),B=new RegExp("^"+A+"$"),W={ID:new RegExp("^#("+A+")"),CLASS:new RegExp("^\\.("+A+")"),TAG:new RegExp("^("+A+"|[*])"),ATTR:new RegExp("^"+R),PSEUDO:new RegExp("^"+M),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+z+"*(even|odd|(([+-]|)(\\d*)n|)"+z+"*(?:([+-]|)"+z+"*(\\d+)|))"+z+"*\\)|)","i"),bool:new RegExp("^(?:"+C+")$","i"),needsContext:new RegExp("^"+z+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+z+"*((?:-\\d)?\\d*)"+z+"*\\)|)(?=[^-]|$)","i")},Q=/^(?:input|select|textarea|button)$/i,G=/^h\d$/i,Y=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,U=new RegExp("\\\\[\\da-fA-F]{1,6}"+z+"?|\\\\([^\\r\\n\\f])","g"),V=function(t,e){var n="0x"+t.slice(1)-65536;return e||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},X=function(){lt()},Z=dt((function(t){return!0===t.disabled&&O(t,"fieldset")}),{dir:"parentNode",next:"legend"});try{v.apply(r=a.call(D.childNodes),D.childNodes),r[D.childNodes.length].nodeType}catch(t){v={apply:function(t,e){L.apply(t,a.call(e))},call:function(t){L.apply(t,a.call(arguments,1))}}}function J(t,e,n,i){var o,r,s,a,u,c,h,p=e&&e.ownerDocument,y=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==y&&9!==y&&11!==y)return n;if(!i&&(lt(e),e=e||l,f)){if(11!==y&&(u=Y.exec(t)))if(o=u[1]){if(9===y){if(!(s=e.getElementById(o)))return n;if(s.id===o)return v.call(n,s),n}else if(p&&(s=p.getElementById(o))&&J.contains(e,s)&&s.id===o)return v.call(n,s),n}else{if(u[2])return v.apply(n,e.getElementsByTagName(t)),n;if((o=u[3])&&e.getElementsByClassName)return v.apply(n,e.getElementsByClassName(o)),n}if(!(_[t+" "]||d&&d.test(t))){if(h=t,p=e,1===y&&(F.test(t)||I.test(t))){for((p=K.test(t)&&at(e.parentNode)||e)==e&&m.scope||((a=e.getAttribute("id"))?a=x.escapeSelector(a):e.setAttribute("id",a=g)),r=(c=ct(t)).length;r--;)c[r]=(a?"#"+a:":scope")+" "+ft(c[r]);h=c.join(",")}try{return v.apply(n,p.querySelectorAll(h)),n}catch(e){_(t,!0)}finally{a===g&&e.removeAttribute("id")}}}return yt(t.replace(P,"$1"),e,n,i)}function tt(){var t=[];return function n(i,o){return t.push(i+" ")>e.cacheLength&&delete n[t.shift()],n[i+" "]=o}}function et(t){return t[g]=!0,t}function nt(t){var e=l.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function it(t){return function(e){return O(e,"input")&&e.type===t}}function ot(t){return function(e){return(O(e,"input")||O(e,"button"))&&e.type===t}}function rt(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&Z(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function st(t){return et((function(e){return e=+e,et((function(n,i){for(var o,r=t([],n.length,e),s=r.length;s--;)n[o=r[s]]&&(n[o]=!(i[o]=n[o]))}))}))}function at(t){return t&&void 0!==t.getElementsByTagName&&t}function lt(t){var n,i=t?t.ownerDocument||t:D;return i!=l&&9===i.nodeType&&i.documentElement?(u=(l=i).documentElement,f=!x.isXMLDoc(l),p=u.matches||u.webkitMatchesSelector||u.msMatchesSelector,u.msMatchesSelector&&D!=l&&(n=l.defaultView)&&n.top!==n&&n.addEventListener("unload",X),m.getById=nt((function(t){return u.appendChild(t).id=x.expando,!l.getElementsByName||!l.getElementsByName(x.expando).length})),m.disconnectedMatch=nt((function(t){return p.call(t,"*")})),m.scope=nt((function(){return l.querySelectorAll(":scope")})),m.cssHas=nt((function(){try{return l.querySelector(":has(*,:jqfake)"),!1}catch(t){return!0}})),m.getById?(e.filter.ID=function(t){var e=t.replace(U,V);return function(t){return t.getAttribute("id")===e}},e.find.ID=function(t,e){if(void 0!==e.getElementById&&f){var n=e.getElementById(t);return n?[n]:[]}}):(e.filter.ID=function(t){var e=t.replace(U,V);return function(t){var n=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}},e.find.ID=function(t,e){if(void 0!==e.getElementById&&f){var n,i,o,r=e.getElementById(t);if(r){if((n=r.getAttributeNode("id"))&&n.value===t)return[r];for(o=e.getElementsByName(t),i=0;r=o[i++];)if((n=r.getAttributeNode("id"))&&n.value===t)return[r]}return[]}}),e.find.TAG=function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):e.querySelectorAll(t)},e.find.CLASS=function(t,e){if(void 0!==e.getElementsByClassName&&f)return e.getElementsByClassName(t)},d=[],nt((function(t){var e;u.appendChild(t).innerHTML="",t.querySelectorAll("[selected]").length||d.push("\\["+z+"*(?:value|"+C+")"),t.querySelectorAll("[id~="+g+"-]").length||d.push("~="),t.querySelectorAll("a#"+g+"+*").length||d.push(".#.+[+~]"),t.querySelectorAll(":checked").length||d.push(":checked"),(e=l.createElement("input")).setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),u.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(e=l.createElement("input")).setAttribute("name",""),t.appendChild(e),t.querySelectorAll("[name='']").length||d.push("\\["+z+"*name"+z+"*="+z+"*(?:''|\"\")")})),m.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),$=function(t,e){if(t===e)return s=!0,0;var n=!t.compareDocumentPosition-!e.compareDocumentPosition;return n||(1&(n=(t.ownerDocument||t)==(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!m.sortDetached&&e.compareDocumentPosition(t)===n?t===l||t.ownerDocument==D&&J.contains(D,t)?-1:e===l||e.ownerDocument==D&&J.contains(D,e)?1:o?c.call(o,t)-c.call(o,e):0:4&n?-1:1)},l):l}for(t in J.matches=function(t,e){return J(t,null,null,e)},J.matchesSelector=function(t,e){if(lt(t),f&&!_[e+" "]&&(!d||!d.test(e)))try{var n=p.call(t,e);if(n||m.disconnectedMatch||t.document&&11!==t.document.nodeType)return n}catch(t){_(e,!0)}return J(e,l,null,[t]).length>0},J.contains=function(t,e){return(t.ownerDocument||t)!=l&<(t),x.contains(t,e)},J.attr=function(t,n){(t.ownerDocument||t)!=l&<(t);var i=e.attrHandle[n.toLowerCase()],o=i&&h.call(e.attrHandle,n.toLowerCase())?i(t,n,!f):void 0;return void 0!==o?o:t.getAttribute(n)},J.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},x.uniqueSort=function(t){var e,n=[],i=0,r=0;if(s=!m.sortStable,o=!m.sortStable&&a.call(t,0),S.call(t,$),s){for(;e=t[r++];)e===t[r]&&(i=n.push(r));for(;i--;)E.call(t,n[i],1)}return o=null,t},x.fn.uniqueSort=function(){return this.pushStack(x.uniqueSort(a.apply(this)))},e=x.expr={cacheLength:50,createPseudo:et,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(U,V),t[3]=(t[3]||t[4]||t[5]||"").replace(U,V),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||J.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&J.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return W.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&N.test(n)&&(e=ct(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(U,V).toLowerCase();return"*"===t?function(){return!0}:function(t){return O(t,e)}},CLASS:function(t){var e=w[t+" "];return e||(e=new RegExp("(^|"+z+")"+t+"("+z+"|$)"))&&w(t,(function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")}))},ATTR:function(t,e,n){return function(i){var o=J.attr(i,t);return null==o?"!="===e:!e||(o+="","="===e?o===n:"!="===e?o!==n:"^="===e?n&&0===o.indexOf(n):"*="===e?n&&o.indexOf(n)>-1:"$="===e?n&&o.slice(-n.length)===n:"~="===e?(" "+o.replace(H," ")+" ").indexOf(n)>-1:"|="===e&&(o===n||o.slice(0,n.length+1)===n+"-"))}},CHILD:function(t,e,n,i,o){var r="nth"!==t.slice(0,3),s="last"!==t.slice(-4),a="of-type"===e;return 1===i&&0===o?function(t){return!!t.parentNode}:function(e,n,l){var u,c,f,d,h,p=r!==s?"nextSibling":"previousSibling",v=e.parentNode,m=a&&e.nodeName.toLowerCase(),b=!l&&!a,w=!1;if(v){if(r){for(;p;){for(f=e;f=f[p];)if(a?O(f,m):1===f.nodeType)return!1;h=p="only"===t&&!h&&"nextSibling"}return!0}if(h=[s?v.firstChild:v.lastChild],s&&b){for(w=(d=(u=(c=v[g]||(v[g]={}))[t]||[])[0]===y&&u[1])&&u[2],f=d&&v.childNodes[d];f=++d&&f&&f[p]||(w=d=0)||h.pop();)if(1===f.nodeType&&++w&&f===e){c[t]=[y,d,w];break}}else if(b&&(w=d=(u=(c=e[g]||(e[g]={}))[t]||[])[0]===y&&u[1]),!1===w)for(;(f=++d&&f&&f[p]||(w=d=0)||h.pop())&&(!(a?O(f,m):1===f.nodeType)||!++w||(b&&((c=f[g]||(f[g]={}))[t]=[y,w]),f!==e)););return(w-=o)===i||w%i==0&&w/i>=0}}},PSEUDO:function(t,n){var i,o=e.pseudos[t]||e.setFilters[t.toLowerCase()]||J.error("unsupported pseudo: "+t);return o[g]?o(n):o.length>1?(i=[t,t,"",n],e.setFilters.hasOwnProperty(t.toLowerCase())?et((function(t,e){for(var i,r=o(t,n),s=r.length;s--;)t[i=c.call(t,r[s])]=!(e[i]=r[s])})):function(t){return o(t,0,i)}):o}},pseudos:{not:et((function(t){var e=[],n=[],i=gt(t.replace(P,"$1"));return i[g]?et((function(t,e,n,o){for(var r,s=i(t,null,o,[]),a=t.length;a--;)(r=s[a])&&(t[a]=!(e[a]=r))})):function(t,o,r){return e[0]=t,i(e,null,r,n),e[0]=null,!n.pop()}})),has:et((function(t){return function(e){return J(t,e).length>0}})),contains:et((function(t){return t=t.replace(U,V),function(e){return(e.textContent||x.text(e)).indexOf(t)>-1}})),lang:et((function(t){return B.test(t||"")||J.error("unsupported lang: "+t),t=t.replace(U,V).toLowerCase(),function(e){var n;do{if(n=f?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(n=n.toLowerCase())===t||0===n.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}})),target:function(t){var e=i.location&&i.location.hash;return e&&e.slice(1)===t.id},root:function(t){return t===u},focus:function(t){return t===function(){try{return l.activeElement}catch(t){}}()&&l.hasFocus()&&!!(t.type||t.href||~t.tabIndex)},enabled:rt(!1),disabled:rt(!0),checked:function(t){return O(t,"input")&&!!t.checked||O(t,"option")&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!e.pseudos.empty(t)},header:function(t){return G.test(t.nodeName)},input:function(t){return Q.test(t.nodeName)},button:function(t){return O(t,"input")&&"button"===t.type||O(t,"button")},text:function(t){var e;return O(t,"input")&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:st((function(){return[0]})),last:st((function(t,e){return[e-1]})),eq:st((function(t,e,n){return[n<0?n+e:n]})),even:st((function(t,e){for(var n=0;ne?e:n;--i>=0;)t.push(i);return t})),gt:st((function(t,e,n){for(var i=n<0?n+e:n;++i1?function(e,n,i){for(var o=t.length;o--;)if(!t[o](e,n,i))return!1;return!0}:t[0]}function pt(t,e,n,i,o){for(var r,s=[],a=0,l=t.length,u=null!=e;a-1&&(r[u]=!(s[u]=d))}}else h=pt(h===s?h.splice(g,h.length):h),o?o(null,s,h,l):v.apply(s,h)}))}function mt(t){for(var i,o,r,s=t.length,a=e.relative[t[0].type],l=a||e.relative[" "],u=a?1:0,f=dt((function(t){return t===i}),l,!0),d=dt((function(t){return c.call(i,t)>-1}),l,!0),h=[function(t,e,o){var r=!a&&(o||e!=n)||((i=e).nodeType?f(t,e,o):d(t,e,o));return i=null,r}];u1&&ht(h),u>1&&ft(t.slice(0,u-1).concat({value:" "===t[u-2].type?"*":""})).replace(P,"$1"),o,u0,r=t.length>0,s=function(s,a,u,c,d){var h,p,m,g=0,b="0",w=s&&[],k=[],j=n,_=s||r&&e.find.TAG("*",d),$=y+=null==j?1:Math.random()||.1,C=_.length;for(d&&(n=a==l||a||d);b!==C&&null!=(h=_[b]);b++){if(r&&h){for(p=0,a||h.ownerDocument==l||(lt(h),u=!f);m=t[p++];)if(m(h,a||l,u)){v.call(c,h);break}d&&(y=$)}o&&((h=!m&&h)&&g--,s&&w.push(h))}if(g+=b,o&&b!==g){for(p=0;m=i[p++];)m(w,k,a,u);if(s){if(g>0)for(;b--;)w[b]||k[b]||(k[b]=T.call(c));k=pt(k)}v.apply(c,k),d&&!s&&k.length>0&&g+i.length>1&&x.uniqueSort(c)}return d&&(y=$,n=j),w};return o?et(s):s}(s,r)),a.selector=t}return a}function yt(t,n,i,o){var r,s,a,l,u,c="function"==typeof t&&t,d=!o&&ct(t=c.selector||t);if(i=i||[],1===d.length){if((s=d[0]=d[0].slice(0)).length>2&&"ID"===(a=s[0]).type&&9===n.nodeType&&f&&e.relative[s[1].type]){if(!(n=(e.find.ID(a.matches[0].replace(U,V),n)||[])[0]))return i;c&&(n=n.parentNode),t=t.slice(s.shift().value.length)}for(r=W.needsContext.test(t)?0:s.length;r--&&(a=s[r],!e.relative[l=a.type]);)if((u=e.find[l])&&(o=u(a.matches[0].replace(U,V),K.test(s[0].type)&&at(n.parentNode)||n))){if(s.splice(r,1),!(t=o.length&&ft(s)))return v.apply(i,o),i;break}}return(c||gt(t,d))(o,n,!f,i,!n||K.test(t)&&at(n.parentNode)||n),i}ut.prototype=e.filters=e.pseudos,e.setFilters=new ut,m.sortStable=g.split("").sort($).join("")===g,lt(),m.sortDetached=nt((function(t){return 1&t.compareDocumentPosition(l.createElement("fieldset"))})),x.find=J,x.expr[":"]=x.expr.pseudos,x.unique=x.uniqueSort,J.compile=gt,J.select=yt,J.setDocument=lt,J.tokenize=ct,J.escape=x.escapeSelector,J.getText=x.text,J.isXML=x.isXMLDoc,J.selectors=x.expr,J.support=x.support,J.uniqueSort=x.uniqueSort}();var M=function(t,e,n){for(var i=[],o=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(o&&x(t).is(n))break;i.push(t)}return i},H=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},q=x.expr.match.needsContext,I=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function F(t,e,n){return g(e)?x.grep(t,(function(t,i){return!!e.call(t,i,t)!==n})):e.nodeType?x.grep(t,(function(t){return t===e!==n})):"string"!=typeof e?x.grep(t,(function(t){return c.call(e,t)>-1!==n})):x.filter(e,t,n)}x.filter=function(t,e,n){var i=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===i.nodeType?x.find.matchesSelector(i,t)?[i]:[]:x.find.matches(t,x.grep(e,(function(t){return 1===t.nodeType})))},x.fn.extend({find:function(t){var e,n,i=this.length,o=this;if("string"!=typeof t)return this.pushStack(x(t).filter((function(){for(e=0;e1?x.uniqueSort(n):n},filter:function(t){return this.pushStack(F(this,t||[],!1))},not:function(t){return this.pushStack(F(this,t||[],!0))},is:function(t){return!!F(this,"string"==typeof t&&q.test(t)?x(t):t||[],!1).length}});var N,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(x.fn.init=function(t,e,n){var i,o;if(!t)return this;if(n=n||N,"string"==typeof t){if(!(i="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:B.exec(t))||!i[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(i[1]){if(e=e instanceof x?e[0]:e,x.merge(this,x.parseHTML(i[1],e&&e.nodeType?e.ownerDocument||e:b,!0)),I.test(i[1])&&x.isPlainObject(e))for(i in e)g(this[i])?this[i](e[i]):this.attr(i,e[i]);return this}return(o=b.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):g(t)?void 0!==n.ready?n.ready(t):t(x):x.makeArray(t,this)}).prototype=x.fn,N=x(b);var W=/^(?:parents|prev(?:Until|All))/,Q={children:!0,contents:!0,next:!0,prev:!0};function G(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}x.fn.extend({has:function(t){var e=x(t,this),n=e.length;return this.filter((function(){for(var t=0;t-1:1===n.nodeType&&x.find.matchesSelector(n,t))){r.push(n);break}return this.pushStack(r.length>1?x.uniqueSort(r):r)},index:function(t){return t?"string"==typeof t?c.call(x(t),this[0]):c.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(x.uniqueSort(x.merge(this.get(),x(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),x.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return M(t,"parentNode")},parentsUntil:function(t,e,n){return M(t,"parentNode",n)},next:function(t){return G(t,"nextSibling")},prev:function(t){return G(t,"previousSibling")},nextAll:function(t){return M(t,"nextSibling")},prevAll:function(t){return M(t,"previousSibling")},nextUntil:function(t,e,n){return M(t,"nextSibling",n)},prevUntil:function(t,e,n){return M(t,"previousSibling",n)},siblings:function(t){return H((t.parentNode||{}).firstChild,t)},children:function(t){return H(t.firstChild)},contents:function(t){return null!=t.contentDocument&&s(t.contentDocument)?t.contentDocument:(O(t,"template")&&(t=t.content||t),x.merge([],t.childNodes))}},(function(t,e){x.fn[t]=function(n,i){var o=x.map(this,e,n);return"Until"!==t.slice(-5)&&(i=n),i&&"string"==typeof i&&(o=x.filter(i,o)),this.length>1&&(Q[t]||x.uniqueSort(o),W.test(t)&&o.reverse()),this.pushStack(o)}}));var Y=/[^\x20\t\r\n\f]+/g;function K(t){return t}function U(t){throw t}function V(t,e,n,i){var o;try{t&&g(o=t.promise)?o.call(t).done(e).fail(n):t&&g(o=t.then)?o.call(t,e,n):e.apply(void 0,[t].slice(i))}catch(t){n.apply(void 0,[t])}}x.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return x.each(t.match(Y)||[],(function(t,n){e[n]=!0})),e}(t):x.extend({},t);var e,n,i,o,r=[],s=[],a=-1,l=function(){for(o=o||t.once,i=e=!0;s.length;a=-1)for(n=s.shift();++a-1;)r.splice(n,1),n<=a&&a--})),this},has:function(t){return t?x.inArray(t,r)>-1:r.length>0},empty:function(){return r&&(r=[]),this},disable:function(){return o=s=[],r=n="",this},disabled:function(){return!r},lock:function(){return o=s=[],n||e||(r=n=""),this},locked:function(){return!!o},fireWith:function(t,n){return o||(n=[t,(n=n||[]).slice?n.slice():n],s.push(n),e||l()),this},fire:function(){return u.fireWith(this,arguments),this},fired:function(){return!!i}};return u},x.extend({Deferred:function(t){var e=[["notify","progress",x.Callbacks("memory"),x.Callbacks("memory"),2],["resolve","done",x.Callbacks("once memory"),x.Callbacks("once memory"),0,"resolved"],["reject","fail",x.Callbacks("once memory"),x.Callbacks("once memory"),1,"rejected"]],n="pending",o={state:function(){return n},always:function(){return r.done(arguments).fail(arguments),this},catch:function(t){return o.then(null,t)},pipe:function(){var t=arguments;return x.Deferred((function(n){x.each(e,(function(e,i){var o=g(t[i[4]])&&t[i[4]];r[i[1]]((function(){var t=o&&o.apply(this,arguments);t&&g(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[i[0]+"With"](this,o?[t]:arguments)}))})),t=null})).promise()},then:function(t,n,o){var r=0;function s(t,e,n,o){return function(){var a=this,l=arguments,u=function(){var i,u;if(!(t=r&&(n!==U&&(a=void 0,l=[i]),e.rejectWith(a,l))}};t?c():(x.Deferred.getErrorHook?c.error=x.Deferred.getErrorHook():x.Deferred.getStackHook&&(c.error=x.Deferred.getStackHook()),i.setTimeout(c))}}return x.Deferred((function(i){e[0][3].add(s(0,i,g(o)?o:K,i.notifyWith)),e[1][3].add(s(0,i,g(t)?t:K)),e[2][3].add(s(0,i,g(n)?n:U))})).promise()},promise:function(t){return null!=t?x.extend(t,o):o}},r={};return x.each(e,(function(t,i){var s=i[2],a=i[5];o[i[1]]=s.add,a&&s.add((function(){n=a}),e[3-t][2].disable,e[3-t][3].disable,e[0][2].lock,e[0][3].lock),s.add(i[3].fire),r[i[0]]=function(){return r[i[0]+"With"](this===r?void 0:this,arguments),this},r[i[0]+"With"]=s.fireWith})),o.promise(r),t&&t.call(r,r),r},when:function(t){var e=arguments.length,n=e,i=Array(n),o=a.call(arguments),r=x.Deferred(),s=function(t){return function(n){i[t]=this,o[t]=arguments.length>1?a.call(arguments):n,--e||r.resolveWith(i,o)}};if(e<=1&&(V(t,r.done(s(n)).resolve,r.reject,!e),"pending"===r.state()||g(o[n]&&o[n].then)))return r.then();for(;n--;)V(o[n],s(n),r.reject);return r.promise()}});var X=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;x.Deferred.exceptionHook=function(t,e){i.console&&i.console.warn&&t&&X.test(t.name)&&i.console.warn("jQuery.Deferred exception: "+t.message,t.stack,e)},x.readyException=function(t){i.setTimeout((function(){throw t}))};var Z=x.Deferred();function J(){b.removeEventListener("DOMContentLoaded",J),i.removeEventListener("load",J),x.ready()}x.fn.ready=function(t){return Z.then(t).catch((function(t){x.readyException(t)})),this},x.extend({isReady:!1,readyWait:1,ready:function(t){(!0===t?--x.readyWait:x.isReady)||(x.isReady=!0,!0!==t&&--x.readyWait>0||Z.resolveWith(b,[x]))}}),x.ready.then=Z.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?i.setTimeout(x.ready):(b.addEventListener("DOMContentLoaded",J),i.addEventListener("load",J));var tt=function(t,e,n,i,o,r,s){var a=0,l=t.length,u=null==n;if("object"===j(n))for(a in o=!0,n)tt(t,e,a,n[a],!0,r,s);else if(void 0!==i&&(o=!0,g(i)||(s=!0),u&&(s?(e.call(t,i),e=null):(u=e,e=function(t,e,n){return u.call(x(t),n)})),e))for(;a1,null,!0)},removeData:function(t){return this.each((function(){lt.remove(this,t)}))}}),x.extend({queue:function(t,e,n){var i;if(t)return e=(e||"fx")+"queue",i=at.get(t,e),n&&(!i||Array.isArray(n)?i=at.access(t,e,x.makeArray(n)):i.push(n)),i||[]},dequeue:function(t,e){e=e||"fx";var n=x.queue(t,e),i=n.length,o=n.shift(),r=x._queueHooks(t,e);"inprogress"===o&&(o=n.shift(),i--),o&&("fx"===e&&n.unshift("inprogress"),delete r.stop,o.call(t,(function(){x.dequeue(t,e)}),r)),!i&&r&&r.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return at.get(t,n)||at.access(t,n,{empty:x.Callbacks("once memory").add((function(){at.remove(t,[e+"queue",n])}))})}}),x.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length\x20\t\r\n\f]*)/i,Ot=/^$|^module$|\/(?:java|ecma)script/i;_t=b.createDocumentFragment().appendChild(b.createElement("div")),($t=b.createElement("input")).setAttribute("type","radio"),$t.setAttribute("checked","checked"),$t.setAttribute("name","t"),_t.appendChild($t),m.checkClone=_t.cloneNode(!0).cloneNode(!0).lastChild.checked,_t.innerHTML="",m.noCloneChecked=!!_t.cloneNode(!0).lastChild.defaultValue,_t.innerHTML="",m.option=!!_t.lastChild;var Tt={thead:[1,"","
        "],col:[2,"","
        "],tr:[2,"","
        "],td:[3,"","
        "],_default:[0,"",""]};function St(t,e){var n;return n=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&O(t,e)?x.merge([t],n):n}function Et(t,e){for(var n=0,i=t.length;n",""]);var zt=/<|&#?\w+;/;function Pt(t,e,n,i,o){for(var r,s,a,l,u,c,f=e.createDocumentFragment(),d=[],h=0,p=t.length;h-1)o&&o.push(r);else if(u=mt(r),s=St(f.appendChild(r),"script"),u&&Et(s),n)for(c=0;r=s[c++];)Ot.test(r.type||"")&&n.push(r);return f}var At=/^([^.]*)(?:\.(.+)|)/;function Rt(){return!0}function Dt(){return!1}function Lt(t,e,n,i,o,r){var s,a;if("object"==typeof e){for(a in"string"!=typeof n&&(i=i||n,n=void 0),e)Lt(t,a,n,i,e[a],r);return t}if(null==i&&null==o?(o=n,i=n=void 0):null==o&&("string"==typeof n?(o=i,i=void 0):(o=i,i=n,n=void 0)),!1===o)o=Dt;else if(!o)return t;return 1===r&&(s=o,o=function(t){return x().off(t),s.apply(this,arguments)},o.guid=s.guid||(s.guid=x.guid++)),t.each((function(){x.event.add(this,e,o,i,n)}))}function Mt(t,e,n){n?(at.set(t,e,!1),x.event.add(t,e,{namespace:!1,handler:function(t){var n,i=at.get(this,e);if(1&t.isTrigger&&this[e]){if(i)(x.event.special[e]||{}).delegateType&&t.stopPropagation();else if(i=a.call(arguments),at.set(this,e,i),this[e](),n=at.get(this,e),at.set(this,e,!1),i!==n)return t.stopImmediatePropagation(),t.preventDefault(),n}else i&&(at.set(this,e,x.event.trigger(i[0],i.slice(1),this)),t.stopPropagation(),t.isImmediatePropagationStopped=Rt)}})):void 0===at.get(t,e)&&x.event.add(t,e,Rt)}x.event={global:{},add:function(t,e,n,i,o){var r,s,a,l,u,c,f,d,h,p,v,m=at.get(t);if(rt(t))for(n.handler&&(n=(r=n).handler,o=r.selector),o&&x.find.matchesSelector(vt,o),n.guid||(n.guid=x.guid++),(l=m.events)||(l=m.events=Object.create(null)),(s=m.handle)||(s=m.handle=function(e){return void 0!==x&&x.event.triggered!==e.type?x.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(Y)||[""]).length;u--;)h=v=(a=At.exec(e[u])||[])[1],p=(a[2]||"").split(".").sort(),h&&(f=x.event.special[h]||{},h=(o?f.delegateType:f.bindType)||h,f=x.event.special[h]||{},c=x.extend({type:h,origType:v,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:p.join(".")},r),(d=l[h])||((d=l[h]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,i,p,s)||t.addEventListener&&t.addEventListener(h,s)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),o?d.splice(d.delegateCount++,0,c):d.push(c),x.event.global[h]=!0)},remove:function(t,e,n,i,o){var r,s,a,l,u,c,f,d,h,p,v,m=at.hasData(t)&&at.get(t);if(m&&(l=m.events)){for(u=(e=(e||"").match(Y)||[""]).length;u--;)if(h=v=(a=At.exec(e[u])||[])[1],p=(a[2]||"").split(".").sort(),h){for(f=x.event.special[h]||{},d=l[h=(i?f.delegateType:f.bindType)||h]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=r=d.length;r--;)c=d[r],!o&&v!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||i&&i!==c.selector&&("**"!==i||!c.selector)||(d.splice(r,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(t,c));s&&!d.length&&(f.teardown&&!1!==f.teardown.call(t,p,m.handle)||x.removeEvent(t,h,m.handle),delete l[h])}else for(h in l)x.event.remove(t,h+e[u],n,i,!0);x.isEmptyObject(l)&&at.remove(t,"handle events")}},dispatch:function(t){var e,n,i,o,r,s,a=new Array(arguments.length),l=x.event.fix(t),u=(at.get(this,"events")||Object.create(null))[l.type]||[],c=x.event.special[l.type]||{};for(a[0]=l,e=1;e=1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&("click"!==t.type||!0!==u.disabled)){for(r=[],s={},n=0;n-1:x.find(o,this,null,[u]).length),s[o]&&r.push(i);r.length&&a.push({elem:u,handlers:r})}return u=this,l\s*$/g;function Ft(t,e){return O(t,"table")&&O(11!==e.nodeType?e:e.firstChild,"tr")&&x(t).children("tbody")[0]||t}function Nt(t){return t.type=(null!==t.getAttribute("type"))+"/"+t.type,t}function Bt(t){return"true/"===(t.type||"").slice(0,5)?t.type=t.type.slice(5):t.removeAttribute("type"),t}function Wt(t,e){var n,i,o,r,s,a;if(1===e.nodeType){if(at.hasData(t)&&(a=at.get(t).events))for(o in at.remove(e,"handle events"),a)for(n=0,i=a[o].length;n1&&"string"==typeof p&&!m.checkClone&&qt.test(p))return t.each((function(o){var r=t.eq(o);v&&(e[0]=p.call(this,o,r.html())),Gt(r,e,n,i)}));if(d&&(r=(o=Pt(e,t[0].ownerDocument,!1,t,i)).firstChild,1===o.childNodes.length&&(o=r),r||i)){for(a=(s=x.map(St(o,"script"),Nt)).length;f0&&Et(s,!l&&St(t,"script")),a},cleanData:function(t){for(var e,n,i,o=x.event.special,r=0;void 0!==(n=t[r]);r++)if(rt(n)){if(e=n[at.expando]){if(e.events)for(i in e.events)o[i]?x.event.remove(n,i):x.removeEvent(n,i,e.handle);n[at.expando]=void 0}n[lt.expando]&&(n[lt.expando]=void 0)}}}),x.fn.extend({detach:function(t){return Yt(this,t,!0)},remove:function(t){return Yt(this,t)},text:function(t){return tt(this,(function(t){return void 0===t?x.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=t)}))}),null,t,arguments.length)},append:function(){return Gt(this,arguments,(function(t){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Ft(this,t).appendChild(t)}))},prepend:function(){return Gt(this,arguments,(function(t){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var e=Ft(this,t);e.insertBefore(t,e.firstChild)}}))},before:function(){return Gt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this)}))},after:function(){return Gt(this,arguments,(function(t){this.parentNode&&this.parentNode.insertBefore(t,this.nextSibling)}))},empty:function(){for(var t,e=0;null!=(t=this[e]);e++)1===t.nodeType&&(x.cleanData(St(t,!1)),t.textContent="");return this},clone:function(t,e){return t=null!=t&&t,e=null==e?t:e,this.map((function(){return x.clone(this,t,e)}))},html:function(t){return tt(this,(function(t){var e=this[0]||{},n=0,i=this.length;if(void 0===t&&1===e.nodeType)return e.innerHTML;if("string"==typeof t&&!Ht.test(t)&&!Tt[(Ct.exec(t)||["",""])[1].toLowerCase()]){t=x.htmlPrefilter(t);try{for(;n=0&&(l+=Math.max(0,Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-r-l-a-.5))||0),l+u}function ce(t,e,n){var i=Vt(t),o=(!m.boxSizingReliable()||n)&&"border-box"===x.css(t,"boxSizing",!1,i),r=o,s=Jt(t,e,i),a="offset"+e[0].toUpperCase()+e.slice(1);if(Kt.test(s)){if(!n)return s;s="auto"}return(!m.boxSizingReliable()&&o||!m.reliableTrDimensions()&&O(t,"tr")||"auto"===s||!parseFloat(s)&&"inline"===x.css(t,"display",!1,i))&&t.getClientRects().length&&(o="border-box"===x.css(t,"boxSizing",!1,i),(r=a in t)&&(s=t[a])),(s=parseFloat(s)||0)+ue(t,e,n||(o?"border":"content"),r,i,s)+"px"}function fe(t,e,n,i,o){return new fe.prototype.init(t,e,n,i,o)}x.extend({cssHooks:{opacity:{get:function(t,e){if(e){var n=Jt(t,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(t,e,n,i){if(t&&3!==t.nodeType&&8!==t.nodeType&&t.style){var o,r,s,a=ot(e),l=Ut.test(e),u=t.style;if(l||(e=oe(a)),s=x.cssHooks[e]||x.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(o=s.get(t,!1,i))?o:u[e];"string"==(r=typeof n)&&(o=ht.exec(n))&&o[1]&&(n=bt(t,e,o),r="number"),null!=n&&n==n&&("number"!==r||l||(n+=o&&o[3]||(x.cssNumber[a]?"":"px")),m.clearCloneStyle||""!==n||0!==e.indexOf("background")||(u[e]="inherit"),s&&"set"in s&&void 0===(n=s.set(t,n,i))||(l?u.setProperty(e,n):u[e]=n))}},css:function(t,e,n,i){var o,r,s,a=ot(e);return Ut.test(e)||(e=oe(a)),(s=x.cssHooks[e]||x.cssHooks[a])&&"get"in s&&(o=s.get(t,!0,n)),void 0===o&&(o=Jt(t,e,i)),"normal"===o&&e in ae&&(o=ae[e]),""===n||n?(r=parseFloat(o),!0===n||isFinite(r)?r||0:o):o}}),x.each(["height","width"],(function(t,e){x.cssHooks[e]={get:function(t,n,i){if(n)return!re.test(x.css(t,"display"))||t.getClientRects().length&&t.getBoundingClientRect().width?ce(t,e,i):Xt(t,se,(function(){return ce(t,e,i)}))},set:function(t,n,i){var o,r=Vt(t),s=!m.scrollboxSize()&&"absolute"===r.position,a=(s||i)&&"border-box"===x.css(t,"boxSizing",!1,r),l=i?ue(t,e,i,a,r):0;return a&&s&&(l-=Math.ceil(t["offset"+e[0].toUpperCase()+e.slice(1)]-parseFloat(r[e])-ue(t,e,"border",!1,r)-.5)),l&&(o=ht.exec(n))&&"px"!==(o[3]||"px")&&(t.style[e]=n,n=x.css(t,e)),le(0,n,l)}}})),x.cssHooks.marginLeft=te(m.reliableMarginLeft,(function(t,e){if(e)return(parseFloat(Jt(t,"marginLeft"))||t.getBoundingClientRect().left-Xt(t,{marginLeft:0},(function(){return t.getBoundingClientRect().left})))+"px"})),x.each({margin:"",padding:"",border:"Width"},(function(t,e){x.cssHooks[t+e]={expand:function(n){for(var i=0,o={},r="string"==typeof n?n.split(" "):[n];i<4;i++)o[t+pt[i]+e]=r[i]||r[i-2]||r[0];return o}},"margin"!==t&&(x.cssHooks[t+e].set=le)})),x.fn.extend({css:function(t,e){return tt(this,(function(t,e,n){var i,o,r={},s=0;if(Array.isArray(e)){for(i=Vt(t),o=e.length;s1)}}),x.Tween=fe,fe.prototype={constructor:fe,init:function(t,e,n,i,o,r){this.elem=t,this.prop=n,this.easing=o||x.easing._default,this.options=e,this.start=this.now=this.cur(),this.end=i,this.unit=r||(x.cssNumber[n]?"":"px")},cur:function(){var t=fe.propHooks[this.prop];return t&&t.get?t.get(this):fe.propHooks._default.get(this)},run:function(t){var e,n=fe.propHooks[this.prop];return this.options.duration?this.pos=e=x.easing[this.easing](t,this.options.duration*t,0,1,this.options.duration):this.pos=e=t,this.now=(this.end-this.start)*e+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):fe.propHooks._default.set(this),this}},fe.prototype.init.prototype=fe.prototype,fe.propHooks={_default:{get:function(t){var e;return 1!==t.elem.nodeType||null!=t.elem[t.prop]&&null==t.elem.style[t.prop]?t.elem[t.prop]:(e=x.css(t.elem,t.prop,""))&&"auto"!==e?e:0},set:function(t){x.fx.step[t.prop]?x.fx.step[t.prop](t):1!==t.elem.nodeType||!x.cssHooks[t.prop]&&null==t.elem.style[oe(t.prop)]?t.elem[t.prop]=t.now:x.style(t.elem,t.prop,t.now+t.unit)}}},fe.propHooks.scrollTop=fe.propHooks.scrollLeft={set:function(t){t.elem.nodeType&&t.elem.parentNode&&(t.elem[t.prop]=t.now)}},x.easing={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},_default:"swing"},x.fx=fe.prototype.init,x.fx.step={};var de,he,pe=/^(?:toggle|show|hide)$/,ve=/queueHooks$/;function me(){he&&(!1===b.hidden&&i.requestAnimationFrame?i.requestAnimationFrame(me):i.setTimeout(me,x.fx.interval),x.fx.tick())}function ge(){return i.setTimeout((function(){de=void 0})),de=Date.now()}function ye(t,e){var n,i=0,o={height:t};for(e=e?1:0;i<4;i+=2-e)o["margin"+(n=pt[i])]=o["padding"+n]=t;return e&&(o.opacity=o.width=t),o}function be(t,e,n){for(var i,o=(we.tweeners[e]||[]).concat(we.tweeners["*"]),r=0,s=o.length;r1)},removeAttr:function(t){return this.each((function(){x.removeAttr(this,t)}))}}),x.extend({attr:function(t,e,n){var i,o,r=t.nodeType;if(3!==r&&8!==r&&2!==r)return void 0===t.getAttribute?x.prop(t,e,n):(1===r&&x.isXMLDoc(t)||(o=x.attrHooks[e.toLowerCase()]||(x.expr.match.bool.test(e)?ke:void 0)),void 0!==n?null===n?void x.removeAttr(t,e):o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:(t.setAttribute(e,n+""),n):o&&"get"in o&&null!==(i=o.get(t,e))?i:null==(i=x.find.attr(t,e))?void 0:i)},attrHooks:{type:{set:function(t,e){if(!m.radioValue&&"radio"===e&&O(t,"input")){var n=t.value;return t.setAttribute("type",e),n&&(t.value=n),e}}}},removeAttr:function(t,e){var n,i=0,o=e&&e.match(Y);if(o&&1===t.nodeType)for(;n=o[i++];)t.removeAttribute(n)}}),ke={set:function(t,e,n){return!1===e?x.removeAttr(t,n):t.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\w+/g),(function(t,e){var n=je[e]||x.find.attr;je[e]=function(t,e,i){var o,r,s=e.toLowerCase();return i||(r=je[s],je[s]=o,o=null!=n(t,e,i)?s:null,je[s]=r),o}}));var _e=/^(?:input|select|textarea|button)$/i,$e=/^(?:a|area)$/i;function xe(t){return(t.match(Y)||[]).join(" ")}function Ce(t){return t.getAttribute&&t.getAttribute("class")||""}function Oe(t){return Array.isArray(t)?t:"string"==typeof t&&t.match(Y)||[]}x.fn.extend({prop:function(t,e){return tt(this,x.prop,t,e,arguments.length>1)},removeProp:function(t){return this.each((function(){delete this[x.propFix[t]||t]}))}}),x.extend({prop:function(t,e,n){var i,o,r=t.nodeType;if(3!==r&&8!==r&&2!==r)return 1===r&&x.isXMLDoc(t)||(e=x.propFix[e]||e,o=x.propHooks[e]),void 0!==n?o&&"set"in o&&void 0!==(i=o.set(t,n,e))?i:t[e]=n:o&&"get"in o&&null!==(i=o.get(t,e))?i:t[e]},propHooks:{tabIndex:{get:function(t){var e=x.find.attr(t,"tabindex");return e?parseInt(e,10):_e.test(t.nodeName)||$e.test(t.nodeName)&&t.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),m.optSelected||(x.propHooks.selected={get:function(t){var e=t.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(t){var e=t.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){x.propFix[this.toLowerCase()]=this})),x.fn.extend({addClass:function(t){var e,n,i,o,r,s;return g(t)?this.each((function(e){x(this).addClass(t.call(this,e,Ce(this)))})):(e=Oe(t)).length?this.each((function(){if(i=Ce(this),n=1===this.nodeType&&" "+xe(i)+" "){for(r=0;r-1;)n=n.replace(" "+o+" "," ");s=xe(n),i!==s&&this.setAttribute("class",s)}})):this:this.attr("class","")},toggleClass:function(t,e){var n,i,o,r,s=typeof t,a="string"===s||Array.isArray(t);return g(t)?this.each((function(n){x(this).toggleClass(t.call(this,n,Ce(this),e),e)})):"boolean"==typeof e&&a?e?this.addClass(t):this.removeClass(t):(n=Oe(t),this.each((function(){if(a)for(r=x(this),o=0;o-1)return!0;return!1}});var Te=/\r/g;x.fn.extend({val:function(t){var e,n,i,o=this[0];return arguments.length?(i=g(t),this.each((function(n){var o;1===this.nodeType&&(null==(o=i?t.call(this,n,x(this).val()):t)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=x.map(o,(function(t){return null==t?"":t+""}))),(e=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()])&&"set"in e&&void 0!==e.set(this,o,"value")||(this.value=o))}))):o?(e=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()])&&"get"in e&&void 0!==(n=e.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(Te,""):null==n?"":n:void 0}}),x.extend({valHooks:{option:{get:function(t){var e=x.find.attr(t,"value");return null!=e?e:xe(x.text(t))}},select:{get:function(t){var e,n,i,o=t.options,r=t.selectedIndex,s="select-one"===t.type,a=s?null:[],l=s?r+1:o.length;for(i=r<0?l:s?r:0;i-1)&&(n=!0);return n||(t.selectedIndex=-1),r}}}}),x.each(["radio","checkbox"],(function(){x.valHooks[this]={set:function(t,e){if(Array.isArray(e))return t.checked=x.inArray(x(t).val(),e)>-1}},m.checkOn||(x.valHooks[this].get=function(t){return null===t.getAttribute("value")?"on":t.value})}));var Se=i.location,Ee={guid:Date.now()},ze=/\?/;x.parseXML=function(t){var e,n;if(!t||"string"!=typeof t)return null;try{e=(new i.DOMParser).parseFromString(t,"text/xml")}catch(t){}return n=e&&e.getElementsByTagName("parsererror")[0],e&&!n||x.error("Invalid XML: "+(n?x.map(n.childNodes,(function(t){return t.textContent})).join("\n"):t)),e};var Pe=/^(?:focusinfocus|focusoutblur)$/,Ae=function(t){t.stopPropagation()};x.extend(x.event,{trigger:function(t,e,n,o){var r,s,a,l,u,c,f,d,p=[n||b],v=h.call(t,"type")?t.type:t,m=h.call(t,"namespace")?t.namespace.split("."):[];if(s=d=a=n=n||b,3!==n.nodeType&&8!==n.nodeType&&!Pe.test(v+x.event.triggered)&&(v.indexOf(".")>-1&&(m=v.split("."),v=m.shift(),m.sort()),u=v.indexOf(":")<0&&"on"+v,(t=t[x.expando]?t:new x.Event(v,"object"==typeof t&&t)).isTrigger=o?2:3,t.namespace=m.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=n),e=null==e?[t]:x.makeArray(e,[t]),f=x.event.special[v]||{},o||!f.trigger||!1!==f.trigger.apply(n,e))){if(!o&&!f.noBubble&&!y(n)){for(l=f.delegateType||v,Pe.test(l+v)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(n.ownerDocument||b)&&p.push(a.defaultView||a.parentWindow||i)}for(r=0;(s=p[r++])&&!t.isPropagationStopped();)d=s,t.type=r>1?l:f.bindType||v,(c=(at.get(s,"events")||Object.create(null))[t.type]&&at.get(s,"handle"))&&c.apply(s,e),(c=u&&s[u])&&c.apply&&rt(s)&&(t.result=c.apply(s,e),!1===t.result&&t.preventDefault());return t.type=v,o||t.isDefaultPrevented()||f._default&&!1!==f._default.apply(p.pop(),e)||!rt(n)||u&&g(n[v])&&!y(n)&&((a=n[u])&&(n[u]=null),x.event.triggered=v,t.isPropagationStopped()&&d.addEventListener(v,Ae),n[v](),t.isPropagationStopped()&&d.removeEventListener(v,Ae),x.event.triggered=void 0,a&&(n[u]=a)),t.result}},simulate:function(t,e,n){var i=x.extend(new x.Event,n,{type:t,isSimulated:!0});x.event.trigger(i,null,e)}}),x.fn.extend({trigger:function(t,e){return this.each((function(){x.event.trigger(t,e,this)}))},triggerHandler:function(t,e){var n=this[0];if(n)return x.event.trigger(t,e,n,!0)}});var Re=/\[\]$/,De=/\r?\n/g,Le=/^(?:submit|button|image|reset|file)$/i,Me=/^(?:input|select|textarea|keygen)/i;function He(t,e,n,i){var o;if(Array.isArray(e))x.each(e,(function(e,o){n||Re.test(t)?i(t,o):He(t+"["+("object"==typeof o&&null!=o?e:"")+"]",o,n,i)}));else if(n||"object"!==j(e))i(t,e);else for(o in e)He(t+"["+o+"]",e[o],n,i)}x.param=function(t,e){var n,i=[],o=function(t,e){var n=g(e)?e():e;i[i.length]=encodeURIComponent(t)+"="+encodeURIComponent(null==n?"":n)};if(null==t)return"";if(Array.isArray(t)||t.jquery&&!x.isPlainObject(t))x.each(t,(function(){o(this.name,this.value)}));else for(n in t)He(n,t[n],e,o);return i.join("&")},x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var t=x.prop(this,"elements");return t?x.makeArray(t):this})).filter((function(){var t=this.type;return this.name&&!x(this).is(":disabled")&&Me.test(this.nodeName)&&!Le.test(t)&&(this.checked||!xt.test(t))})).map((function(t,e){var n=x(this).val();return null==n?null:Array.isArray(n)?x.map(n,(function(t){return{name:e.name,value:t.replace(De,"\r\n")}})):{name:e.name,value:n.replace(De,"\r\n")}})).get()}});var qe=/%20/g,Ie=/#.*$/,Fe=/([?&])_=[^&]*/,Ne=/^(.*?):[ \t]*([^\r\n]*)$/gm,Be=/^(?:GET|HEAD)$/,We=/^\/\//,Qe={},Ge={},Ye="*/".concat("*"),Ke=b.createElement("a");function Ue(t){return function(e,n){"string"!=typeof e&&(n=e,e="*");var i,o=0,r=e.toLowerCase().match(Y)||[];if(g(n))for(;i=r[o++];)"+"===i[0]?(i=i.slice(1)||"*",(t[i]=t[i]||[]).unshift(n)):(t[i]=t[i]||[]).push(n)}}function Ve(t,e,n,i){var o={},r=t===Ge;function s(a){var l;return o[a]=!0,x.each(t[a]||[],(function(t,a){var u=a(e,n,i);return"string"!=typeof u||r||o[u]?r?!(l=u):void 0:(e.dataTypes.unshift(u),s(u),!1)})),l}return s(e.dataTypes[0])||!o["*"]&&s("*")}function Xe(t,e){var n,i,o=x.ajaxSettings.flatOptions||{};for(n in e)void 0!==e[n]&&((o[n]?t:i||(i={}))[n]=e[n]);return i&&x.extend(!0,t,i),t}Ke.href=Se.href,x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Se.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Se.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Ye,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(t,e){return e?Xe(Xe(t,x.ajaxSettings),e):Xe(x.ajaxSettings,t)},ajaxPrefilter:Ue(Qe),ajaxTransport:Ue(Ge),ajax:function(t,e){"object"==typeof t&&(e=t,t=void 0),e=e||{};var n,o,r,s,a,l,u,c,f,d,h=x.ajaxSetup({},e),p=h.context||h,v=h.context&&(p.nodeType||p.jquery)?x(p):x.event,m=x.Deferred(),g=x.Callbacks("once memory"),y=h.statusCode||{},w={},k={},j="canceled",_={readyState:0,getResponseHeader:function(t){var e;if(u){if(!s)for(s={};e=Ne.exec(r);)s[e[1].toLowerCase()+" "]=(s[e[1].toLowerCase()+" "]||[]).concat(e[2]);e=s[t.toLowerCase()+" "]}return null==e?null:e.join(", ")},getAllResponseHeaders:function(){return u?r:null},setRequestHeader:function(t,e){return null==u&&(t=k[t.toLowerCase()]=k[t.toLowerCase()]||t,w[t]=e),this},overrideMimeType:function(t){return null==u&&(h.mimeType=t),this},statusCode:function(t){var e;if(t)if(u)_.always(t[_.status]);else for(e in t)y[e]=[y[e],t[e]];return this},abort:function(t){var e=t||j;return n&&n.abort(e),$(0,e),this}};if(m.promise(_),h.url=((t||h.url||Se.href)+"").replace(We,Se.protocol+"//"),h.type=e.method||e.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(Y)||[""],null==h.crossDomain){l=b.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Ke.protocol+"//"+Ke.host!=l.protocol+"//"+l.host}catch(t){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=x.param(h.data,h.traditional)),Ve(Qe,h,e,_),u)return _;for(f in(c=x.event&&h.global)&&0==x.active++&&x.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Be.test(h.type),o=h.url.replace(Ie,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qe,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(ze.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Fe,"$1"),d=(ze.test(o)?"&":"?")+"_="+Ee.guid+++d),h.url=o+d),h.ifModified&&(x.lastModified[o]&&_.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&_.setRequestHeader("If-None-Match",x.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||e.contentType)&&_.setRequestHeader("Content-Type",h.contentType),_.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Ye+"; q=0.01":""):h.accepts["*"]),h.headers)_.setRequestHeader(f,h.headers[f]);if(h.beforeSend&&(!1===h.beforeSend.call(p,_,h)||u))return _.abort();if(j="abort",g.add(h.complete),_.done(h.success),_.fail(h.error),n=Ve(Ge,h,e,_)){if(_.readyState=1,c&&v.trigger("ajaxSend",[_,h]),u)return _;h.async&&h.timeout>0&&(a=i.setTimeout((function(){_.abort("timeout")}),h.timeout));try{u=!1,n.send(w,$)}catch(t){if(u)throw t;$(-1,t)}}else $(-1,"No Transport");function $(t,e,s,l){var f,d,b,w,k,j=e;u||(u=!0,a&&i.clearTimeout(a),n=void 0,r=l||"",_.readyState=t>0?4:0,f=t>=200&&t<300||304===t,s&&(w=function(t,e,n){for(var i,o,r,s,a=t.contents,l=t.dataTypes;"*"===l[0];)l.shift(),void 0===i&&(i=t.mimeType||e.getResponseHeader("Content-Type"));if(i)for(o in a)if(a[o]&&a[o].test(i)){l.unshift(o);break}if(l[0]in n)r=l[0];else{for(o in n){if(!l[0]||t.converters[o+" "+l[0]]){r=o;break}s||(s=o)}r=r||s}if(r)return r!==l[0]&&l.unshift(r),n[r]}(h,_,s)),!f&&x.inArray("script",h.dataTypes)>-1&&x.inArray("json",h.dataTypes)<0&&(h.converters["text script"]=function(){}),w=function(t,e,n,i){var o,r,s,a,l,u={},c=t.dataTypes.slice();if(c[1])for(s in t.converters)u[s.toLowerCase()]=t.converters[s];for(r=c.shift();r;)if(t.responseFields[r]&&(n[t.responseFields[r]]=e),!l&&i&&t.dataFilter&&(e=t.dataFilter(e,t.dataType)),l=r,r=c.shift())if("*"===r)r=l;else if("*"!==l&&l!==r){if(!(s=u[l+" "+r]||u["* "+r]))for(o in u)if((a=o.split(" "))[1]===r&&(s=u[l+" "+a[0]]||u["* "+a[0]])){!0===s?s=u[o]:!0!==u[o]&&(r=a[0],c.unshift(a[1]));break}if(!0!==s)if(s&&t.throws)e=s(e);else try{e=s(e)}catch(t){return{state:"parsererror",error:s?t:"No conversion from "+l+" to "+r}}}return{state:"success",data:e}}(h,w,_,f),f?(h.ifModified&&((k=_.getResponseHeader("Last-Modified"))&&(x.lastModified[o]=k),(k=_.getResponseHeader("etag"))&&(x.etag[o]=k)),204===t||"HEAD"===h.type?j="nocontent":304===t?j="notmodified":(j=w.state,d=w.data,f=!(b=w.error))):(b=j,!t&&j||(j="error",t<0&&(t=0))),_.status=t,_.statusText=(e||j)+"",f?m.resolveWith(p,[d,j,_]):m.rejectWith(p,[_,j,b]),_.statusCode(y),y=void 0,c&&v.trigger(f?"ajaxSuccess":"ajaxError",[_,h,f?d:b]),g.fireWith(p,[_,j]),c&&(v.trigger("ajaxComplete",[_,h]),--x.active||x.event.trigger("ajaxStop")))}return _},getJSON:function(t,e,n){return x.get(t,e,n,"json")},getScript:function(t,e){return x.get(t,void 0,e,"script")}}),x.each(["get","post"],(function(t,e){x[e]=function(t,n,i,o){return g(n)&&(o=o||i,i=n,n=void 0),x.ajax(x.extend({url:t,type:e,dataType:o,data:n,success:i},x.isPlainObject(t)&&t))}})),x.ajaxPrefilter((function(t){var e;for(e in t.headers)"content-type"===e.toLowerCase()&&(t.contentType=t.headers[e]||"")})),x._evalUrl=function(t,e,n){return x.ajax({url:t,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(t){x.globalEval(t,e,n)}})},x.fn.extend({wrapAll:function(t){var e;return this[0]&&(g(t)&&(t=t.call(this[0])),e=x(t,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map((function(){for(var t=this;t.firstElementChild;)t=t.firstElementChild;return t})).append(this)),this},wrapInner:function(t){return g(t)?this.each((function(e){x(this).wrapInner(t.call(this,e))})):this.each((function(){var e=x(this),n=e.contents();n.length?n.wrapAll(t):e.append(t)}))},wrap:function(t){var e=g(t);return this.each((function(n){x(this).wrapAll(e?t.call(this,n):t)}))},unwrap:function(t){return this.parent(t).not("body").each((function(){x(this).replaceWith(this.childNodes)})),this}}),x.expr.pseudos.hidden=function(t){return!x.expr.pseudos.visible(t)},x.expr.pseudos.visible=function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)},x.ajaxSettings.xhr=function(){try{return new i.XMLHttpRequest}catch(t){}};var Ze={0:200,1223:204},Je=x.ajaxSettings.xhr();m.cors=!!Je&&"withCredentials"in Je,m.ajax=Je=!!Je,x.ajaxTransport((function(t){var e,n;if(m.cors||Je&&!t.crossDomain)return{send:function(o,r){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];for(s in t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest"),o)a.setRequestHeader(s,o[s]);e=function(t){return function(){e&&(e=n=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===t?a.abort():"error"===t?"number"!=typeof a.status?r(0,"error"):r(a.status,a.statusText):r(Ze[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=e(),n=a.onerror=a.ontimeout=e("error"),void 0!==a.onabort?a.onabort=n:a.onreadystatechange=function(){4===a.readyState&&i.setTimeout((function(){e&&n()}))},e=e("abort");try{a.send(t.hasContent&&t.data||null)}catch(t){if(e)throw t}},abort:function(){e&&e()}}})),x.ajaxPrefilter((function(t){t.crossDomain&&(t.contents.script=!1)})),x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(t){return x.globalEval(t),t}}}),x.ajaxPrefilter("script",(function(t){void 0===t.cache&&(t.cache=!1),t.crossDomain&&(t.type="GET")})),x.ajaxTransport("script",(function(t){var e,n;if(t.crossDomain||t.scriptAttrs)return{send:function(i,o){e=x(" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Build an IoT App with Go

        +
        +

        Introduction

        +

        In this section, we will walk you through the CarePet commands and explain the code behind them.

        +

        As explained in Getting Started with CarePet, the project is structured as follows:

        +
          +
        • Migrate (/cmd/migrate) - Creates the CarePet keyspace and tables.

        • +
        • Collar (/cmd/sensor) - Simulates a pet’s collar by generating the pet’s health data and pushing the data into the storage.

        • +
        • Server (/cmd/server) - REST API service for tracking the pets’ health state.

        • +
        +
        +
        +

        Migrate

        +

        The /migrate command creates the keyspace and tables that will be used by the collar and server services.

        +

        Line 25 to 27 in the /cmd/migrate/migrate.go file call the createKeyspace , migrateKeyspace then the printKeyspaceMetadata functions.

        +
        func main() {
        +	
        +	/// ...
        +
        +	createKeyspace()
        +	migrateKeyspace()
        +	printKeyspaceMetadata()
        +}
        +
        +
        +

        The createKeyspace function creates a new session then executes the following CQL query stored in the db.go file:

        +
        CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' } AND durable_writes = TRUE;
        +
        +
        +
        func createKeyspace() {
        +        // Creates a new session
        +	ses, err := config.Session()
        +	if err != nil {
        +		log.Fatalln("session: ", err)
        +	}
        +	defer ses.Close()
        +
        +        // Executes the CREATE KEYSPACE query and checks for errors
        +	if err := ses.Query(db.KeySpaceCQL).Exec(); err != nil {
        +		log.Fatalln("ensure keyspace exists: ", err)
        +	}
        +}
        +
        +
        +

        The migrateKeyspace function opens a new session with the carepet keyspace and creates the following tables in the carepet keyspace using the CQL file located in /db/cql/care-pet-ddl.cql:

        +
          +
        • owner

        • +
        • pet

        • +
        • sensor

        • +
        • measurement

        • +
        • sensor_avg

        • +
        +
        func migrateKeyspace() {
        +        // Create a new session with the carepet keyspace 
        +	ses, err := config.Keyspace()
        +	if err != nil {
        +		log.Fatalln("session: ", err)
        +	}
        +	defer ses.Close()
        +
        +        // Execute the queries in the migration file om db/cql
        +	if err := migrate.Migrate(context.Background(), ses, "db/cql"); err != nil {
        +		log.Fatalln("migrate: ", err)
        +	}
        +}
        +
        +
        +

        As the name suggests, the printKeyspaceMetadata function will then print the metadata related to the carepet keyspace and confirm that the tables were properly created.

        +
        +
        +

        Sensor

        +

        The sensor service simulates the collar’s activity. The service uses the pet struct and its functions defined in sensor/pet.go to create a new pet along with an owner and sensorType then saves it to the database.

        +
        func main() {
        +
        +	/// ...
        +
        +	// Create a new session with carepet keyspace
        +	ses, err := config.Keyspace()
        +	if err != nil {
        +		log.Fatalln("session: ", err)
        +	}
        +	defer ses.Close()
        +
        +	// Generate new pet
        +	pet := NewPet()
        +
        +	// Save new pet to the database
        +	if err := pet.save(context.Background(), ses); err != nil {
        +		log.Fatalln("pet save: ", err)
        +	}
        +
        +	log.Println("New owner #", pet.p.OwnerID)
        +	log.Println("New pet #", pet.p.PetID)
        +
        +	pet.run(context.Background(), ses)
        +}
        +
        +
        +
        +
        +

        Server

        +

        The server service is a REST API for tracking the pets’ health state. The service allows users to query the database via http.

        +

        In the care-pet example, you will use $ curl http://127.0.0.1:8000/api/owner/{id} and expect the following response:

        +
        [{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}]
        +
        +
        +

        Let’s first discuss the code from line 23 to 28 in server/main.go.

        +
        func main() {
        +
        +	// ...
        +	
        +	api := operations.NewCarePetAPI(spec())
        +	server := restapi.NewServer(api)
        +	defer server.Shutdown()
        +
        +	configure(server)
        +	server.ConfigureAPI()
        +
        +	// ...
        +
        +}
        +
        +
        +

        The api object represent a list of functions and codes generated by the swagger tool. Those operations are then passed to the NewServer method to configure the API and handler methods:

        +
        // ConfigureAPI configures the API and handlers.
        +func (s *Server) ConfigureAPI() {
        +	if s.api != nil {
        +		s.handler = configureAPI(s.api)
        +	}
        +}
        +
        +
        +

        One example of a handler method is the FindOwnerByID in handler/owner.go.

        +
        func FindOwnerByID(ses gocqlx.Session) operations.FindOwnerByIDHandlerFunc {
        +	return func(params operations.FindOwnerByIDParams) middleware.Responder {
        +		var owner model.Owner
        +
        +		if err := db.TableOwner.GetQuery(ses).Bind(params.ID.String()).GetRelease(&owner); err == gocql.ErrNotFound {
        +			// Returns FindOwnerByIDDefault with with status code 404
        +			return operations.NewFindOwnerByIDDefault(http.StatusNotFound)
        +		} else if err != nil {
        +			log.Println("find owner by id query: ", err)
        +			// Returns FindOwnerByIDDefault with with status code 500
        +			return operations.NewFindOwnerByIDDefault(http.StatusInternalServerError)
        +		}
        +
        +		// Return status 200 and owner information
        +		return &operations.FindOwnerByIDOK{Payload: &models.Owner{
        +			Address: owner.Address,
        +			Name:    owner.Name,
        +			OwnerID: conv.UUID(strfmt.UUID(owner.OwnerID.String())),
        +		}}
        +	}
        +}
        +
        +
        +

        Line 25 queries the owner table then saves the result in the owner object or throws a not found 404 status error.

        +

        Line 32 returns a FindOwnerByIDOK object with code status 200 and the owner’s information.

        +
        +
        +

        Resources

        + +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/build-with-java.html b/stable/build-with-java.html new file mode 100644 index 00000000..1e40bd75 --- /dev/null +++ b/stable/build-with-java.html @@ -0,0 +1,771 @@ + + + + + + + + + + + + + Build an IoT App with Java | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Build an IoT App with Java

        +
        +

        Architecture

        +

        In this section, we will walk you through the CarePet commands and explain the code behind them. +The project is structured as follows:

        +
          +
        • Migrate (com.carepet.Migrate) - Creates the carepet keyspace and tables.

        • +
        • Collar (com.carepet.Sensor) - Generates pet health data and pushes it into the storage.

        • +
        • Web app (com.carepet.server.App) - REST API service for tracking pets’ health state.

        • +
        +
        +
        +

        Migrate

        +

        The ./bin/migrate.sh --hosts $NODE1 --datacenter datacenter1 command executes the main function in the Migrate class located Migrate.java. The function creates the keyspace and tables used by the collar and server services.

        +

        The following code in the Migrate.java file calls the createKeyspace , createSchema , and printMetadata functions.

        +
        public static void main(String[] args) {
        +	final Config config = Config.parse(new Config(), args);
        +
        +	final Migrate client = new Migrate(config);
        +	client.createKeyspace();
        +	client.createSchema();
        +	client.printMetadata();
        +}
        +
        +
        +

        Let’s break down the code line by line.

        +

        The config object parses the arguments passed in the migrate command. In our case it’s hosts and datacenter. The hosts argument expects the IP address of one of the nodes. The datacenter argument is datacenter1 by default but could be different if you use Scylla Cloud. The command also accepts username and password arguments if required.

        +

        The createKeyspace function creates a new CqlSession, then executes the following CQL query stored in the resources/care-pet-keyspace.cql file:

        +
        public void createKeyspace() {
        +	LOG.info("creating keyspace...");
        +	try (CqlSession session = connect()) {
        +			session.execute(Config.getResource("care-pet-keyspace.cql"));
        +	}
        +}
        +
        +
        +
        CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' } AND durable_writes = TRUE;
        +
        +
        +

        The CQL query above creates a new keyspace named carepet, with NetworkTopologyStrategy as replication strategy and a replication factor of 3. +See Scylla University for more information about keyspaces and replication.

        +

        The createSchema function opens a new session with the carepet keyspace and creates the following tables in the carepet keyspace using the CQL file located in resources/care-pet-ddl.cql:

        +
          +
        • owner

        • +
        • pet

        • +
        • sensor

        • +
        • measurement

        • +
        • sensor_avg

        • +
        +
        public void createSchema() {
        +	LOG.info("creating table...");
        +	try (CqlSession session = keyspace()) {
        +	    for (String cql : Config.getResource("care-pet-ddl.cql").split(";")) {
        +		session.execute(cql);
        +	    }
        +	}
        +}
        +
        +
        +

        The printMetadata function will print the metadata related to the carepet keyspace and confirm that the tables are properly created.

        +

        You can check the database structure with:

        +
        $ docker exec -it carepet-scylla1 cqlsh
        +cqlsh> USE carepet;
        +cqlsh:carepet> DESCRIBE TABLES
        +cqlsh:carepet> DESCRIBE TABLE pet
        +
        +
        +

        You should expect the following result:

        +
        CREATE TABLE carepet.pet (
        +owner_id uuid,
        +pet_id uuid,
        +chip_id text,
        +species text,
        +breed   text,
        +color   text,
        +gender  text,
        +address text,
        +age int,
        +name text,
        +weight float,
        +PRIMARY KEY (owner_id, pet_id)
        +) WITH CLUSTERING ORDER BY (pet_id ASC)
        +AND bloom_filter_fp_chance = 0.01
        +AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
        +AND comment = ''
        +AND compaction = {'class': 'SizeTieredCompactionStrategy'}
        +AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
        +AND crc_check_chance = 1.0
        +AND dclocal_read_repair_chance = 0.1
        +AND default_time_to_live = 0
        +AND gc_grace_seconds = 864000
        +AND max_index_interval = 2048
        +AND memtable_flush_period_in_ms = 0
        +AND min_index_interval = 128
        +AND read_repair_chance = 0.0
        +AND speculative_retry = '99.0PERCENTILE';
        +
        +
        +
        +
        +

        Sensor

        +

        The sensor service simulates the collar’s activity. You can use the following command to run the sensor service:

        +
        $ mvn package
        +$ NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +$ ./bin/sensor.sh --hosts $NODE1 --datacenter datacenter1 --measure PT1M --buffer-interval PT1M
        +
        +
        +

        The above command executes Sensor.java and the following main function:

        +
        public static void main(String[] args) {
        +        final Sensor client = new Sensor(Config.parse(new SensorConfig(), args));
        +        client.save();
        +        client.run();
        +    }
        +}
        +
        +
        +

        First, we create a client object, an instance of the Sensor class. Like in the Migrate class, we parse args using the Config.parse() method to connect to the database.

        +

        In the Sensor constructor, a random ID is attributed to the owner, pet, and sensors.

        +
        public Sensor(SensorConfig config) {
        +	this.config = config;
        +
        +	this.owner = Owner.random();
        +	this.pet = Pet.random(this.owner.getOwnerId());
        +	this.sensors = new com.carepet.model.Sensor[SensorType.values().length];
        +	for (int i = 0; i < this.sensors.length; i++) {
        +			this.sensors[i] = com.carepet.model.Sensor.random(this.pet.getPetId());
        +	}
        +}
        +
        +
        +

        The client.save() method connects to the datbase and saves the generated owner, pet, and the sensors.

        +
        private void save() {
        +	try (CqlSession session = keyspace()) {
        +			// Connect to the database
        +			Mapper m = Mapper.builder(session).build();
        +
        +			LOG.info("owner = " + owner);
        +			LOG.info("pet = " + pet);
        +
        +			m.owner().create(owner);
        +			m.pet().create(pet);
        +
        +			for (com.carepet.model.Sensor s : sensors) {
        +					LOG.info("sensor = " + s);
        +
        +					m.sensor().create(s);
        +			}
        +	}
        +}
        +
        +
        +

        The client.run() generates random data and pushes it to the database. In this code, we are using PreparedStatement to define the query and BatchStatementBuilder to run multiple queries at the same time. See the [Scylla Java Driver documentation] (https://java-driver.docs.scylladb.com/stable/manual/core/statements/prepared/) for details on PreparedStatement.

        +
        private void run() {
        +	try (CqlSession session = keyspace()) {
        +			PreparedStatement statement = session.prepare("INSERT INTO measurement (sensor_id, ts, value) VALUES (?, ?, ?)");
        +			BatchStatementBuilder builder = new BatchStatementBuilder(BatchType.UNLOGGED);
        +
        +			List<Measure> ms = new ArrayList<>();
        +			Instant prev = Instant.now();
        +
        +			while (true) {
        +					while (Duration.between(prev, Instant.now()).compareTo(config.bufferInterval) < 0) {
        +							if (!sleep(config.measurement)) {
        +									return;
        +							}
        +
        +							for (com.carepet.model.Sensor s : sensors) {
        +									Measure m = readSensorData(s);
        +									ms.add(m);
        +									LOG.info(m.toString());
        +							}
        +					}
        +
        +					prev = prev.plusMillis((Duration.between(prev, Instant.now()).toMillis() / config.bufferInterval.toMillis()) * config.bufferInterval.toMillis());
        +
        +					LOG.info("pushing data");
        +					// this is simplified example of batch execution. standard
        +					// best practice is to batch values that end up in the same partition:
        +					// https://www.scylladb.com/2019/03/27/best-practices-for-scylla-applications/
        +					for (Measure m : ms) {
        +							builder = builder.addStatement(statement.bind(m.getSensorId(), m.getTs(), m.getValue()));
        +					}
        +
        +					session.execute(builder.build());
        +
        +					builder.clearStatements();
        +					ms.clear();
        +			}
        +	}
        +}
        +
        +
        +
        +
        +

        Server

        +

        The server service is a REST API for tracking the pets’ health state. The service allows you to query the database via HTTP.

        +

        Run the following commands to start the server:

        +
        $ mvn package
        +$ NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +$ ./bin/server.sh --hosts $NODE1 --datacenter datacenter1
        +
        +
        +

        In the care-pet example, run:

        +

        $ curl http://127.0.0.1:8000/api/owner/{id}.

        +

        You can expect the following response:

        +
        
        +[{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}]
        +
        +
        +
        +

        The controller is defined in ModelController.java, and implements the GET methods to access owners, pets and sensors data.

        +

        The server also aggregates the data and saves it to the database in the sensor_avg table:

        +
        
        +// saveAggregate saves the result monotonically sequentially to the database
        +private void saveAggregate(UUID sensorId, List<Float> data, int prevAvgSize, LocalDate day, LocalDateTime now) {
        +// if it's the same day, we can't aggregate current hour
        +boolean sameDate = now.getDayOfYear() == day.getDayOfYear();
        +int current = now.getHour();
        +
        +        for (int hour = prevAvgSize; hour < data.size(); hour++) {
        +            if (sameDate && hour >= current) {
        +                break;
        +            }
        +
        +            mapper.sensorAvg().create(new SensorAvg(sensorId, day, hour, data.get(hour)));
        +        }
        +    }
        +
        +
        +
        +
        +
        +

        Resources

        + +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/build-with-javascript.html b/stable/build-with-javascript.html new file mode 100644 index 00000000..3b7ab59e --- /dev/null +++ b/stable/build-with-javascript.html @@ -0,0 +1,1077 @@ + + + + + + + + + + + + + Build an IoT App with JavaScript | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Build an IoT App with JavaScript

        +
        +

        Architecture

        +

        In this section, we will walk you through the CarePet commands and explain the code behind them. +The project is structured as follows:

        +

        Build your first ScyllaDB Powered App - Raouf

        +
          +
        • migrate (npm run migrate) - Creates the carepet keyspace and tables.

        • +
        • collar (npm run sensor) - Generates pet health data and pushes it into the storage.

        • +
        • web app (npm run dev) - REST API service for tracking pets’ health state.

        • +
        +
        +
        +

        Code Structure and Implementation

        +

        The code package structure is as follows:

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

        Name

        Purpose

        /

        web application backend

        /api

        API spec

        /cmd

        applications executables

        /cmd/migrate

        install database schema

        /cmd/sensor

        Simulates the pet’s collar

        /config

        database configuration

        /db

        database handlers (gocql/x)

        /db/cql

        database schema

        /handler

        REST API handlers

        /model

        application models and ORM metadata

        +
        +
        +

        Quick Start

        +

        Prerequisites:

        +
          +
        • NodeJS tested with v17.0.1

        • +
        • NPM tested with v8.1.0

        • +
        • docker (not required if you use Scylla Cloud)

        • +
        • docker-compose (not required if you use Scylla Cloud)

        • +
        +

        Clone the repository and change to javascript directory:

        +
        git clone git@github.com:scylladb/care-pet.git
        +cd javascript
        +
        +
        +

        Make sure to install all NodeJS dependencies with:

        +
        $ npm install
        +
        +
        +
        +
        +

        Use ScyllaDB on your local machine

        +

        To run a local ScyllaDB cluster consisting of three nodes with +the help of docker and docker-compose execute:

        +
        $ docker-compose up -d
        +
        +
        +

        Docker-compose will spin up three nodes: carepet-scylla1, carepet-scylla2, +and carepet-scylla3. You can access them with the docker command.

        +

        Execute the following nodetool command:

        +
        $ docker exec -it carepet-scylla1 nodetool status
        +
        +
        +
        +
        +

        Migrate

        +
        +

        Run ScyllaDB on your local machine

        +

        Once all the nodes are in UN - Up Normal status, run the commands below.

        +

        The following command allows you to get the node IP address:

        +
        docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1
        +
        +
        +

        The following commands execute the migrate main function.

        +
        NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +npm run migrate -- --hosts $NODE1
        +
        +
        +

        You can check the database structure with:

        +
        docker exec -it carepet-scylla1 cqlsh
        +
        +
        +
        +
        +

        Using Scylla Cloud

        +

        If you are using Scylla Cloud, use the the following command to run the migrate service:

        +
        npm run migrate -- --hosts [NODE-IP] --username [USERNAME] --password[PASSWORD]
        +
        +
        +

        Replace the NODE-IP, USERNAME, and PASSWORD with the information provided in your cluster on https://cloud.scylladb.com.

        +
        +
        +
        +

        Output

        +

        Expected output:

        +
        2020/08/06 16:43:01 Bootstrap database...
        +2020/08/06 16:43:13 Keyspace metadata = {Name:carepet DurableWrites:true StrategyClass:org.apache.cassandra.locator.NetworkTopologyStrategy StrategyOptions:map[datacenter1:3] Tables:map[gocqlx_migrate:0xc00016ca80 measurement:0xc00016cbb0 owner:0xc00016cce0 pet:0xc00016ce10 sensor:0xc00016cf40 sensor_avg:0xc00016d070] Functions:map[] Aggregates:map[] Types:map[] Indexes:map[] Views:map[]}
        +
        +
        +

        You can check the database structure with:

        +

        docker run -it --rm --entrypoint cqlsh scylladb/scylla -u [USERNAME] -p [PASSWORD] [NODE-IP]

        +

        Note: use -u [USERNAME] and -p [PASSWORD] if you are using Scylla Cloud.

        +

        Once you connect to cqlsh, run the following commands:

        +

        #. Run DESCRIBE KEYSPACES.

        +

        Expected output:

        +
        carepet  system_schema  system_auth  system  system_distributed  system_traces
        +
        +
        +

        then,

        +
         carepet;
        +DESCRIBE TABLES
        +
        +
        +

        Expected output:

        +

        pet  sensor_avg  gocqlx_migrate  measurement  owner  sensor

        +

        #. Run DESCRIBE TABLE pet.

        +

        Expected output:

        +
        CREATE TABLE carepet.pet (
        +       owner_id uuid,
        +       pet_id uuid,
        +       address text,
        +       age int,
        +       breed text,
        +       chip_id text,
        +       color text,
        +       gender text,
        +       name text,
        +       species text,
        +       weight float,
        +       PRIMARY KEY (owner_id, pet_id)  
        +   ) WITH CLUSTERING ORDER BY (pet_id ASC)
        +       AND bloom_filter_fp_chance = 0.01
        +       AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
        +       AND comment = ''
        +       AND compaction = {'class': 'SizeTieredCompactionStrategy'}
        +       AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
        +       AND crc_check_chance = 1.0
        +       AND dclocal_read_repair_chance = 0.1
        +       AND default_time_to_live = 0
        +       AND gc_grace_seconds = 864000
        +       AND max_index_interval = 2048
        +       AND memtable_flush_period_in_ms = 0
        +       AND min_index_interval = 128
        +       AND read_repair_chance = 0.0
        +       AND speculative_retry = '99.0PERCENTILE';
        +
        +
        +

        #. Run exit to exit the cqlsh.

        +
        +

        migrate/index.js

        +

        The above commands execute the main function in the cmd/migrate/index.js. The function creates the keyspace and tables that you need to run the collar and server services.

        +

        The following code in the cmd/migrate/index.js creates a new session, then calls the create_keyspace and migrate functions.

        +
        migrate/index.js
        +
        +async function main() {
        +  // Parse the command arguments: --hosts --username and --password
        +  const options = config('migrate').parse().opts();
        +  
        +  // Create a new session with options 
        +  const client = await getClient(options);
        +
        +  // Create a keyspace
        +  await client.execute(cql.KEYSPACE);
        +  
        +  // Create the tables
        +  for (const query of cql.MIGRATE) {
        +    log.debug(`query = ${query}`);
        +    await client.execute(query);
        +  }
        +
        +  return client;
        +}
        +
        +
        +

        Let’s break down the code above.

        +

        The getClient function takes the options as a parameter and creates a new session.

        +
        // src/db.js
        +
        +async function getClient(config, keyspace) {
        +  const client = new cassandra.Client({
        +    contactPoints: config.hosts,
        +    authProvider: new cassandra.auth.PlainTextAuthProvider(
        +      config.username,
        +      config.password
        +    ),
        +    localDataCenter: 'datacenter1',
        +    keyspace,
        +  });
        +
        +  await client.connect();
        +
        +  return client;
        +}
        +
        +
        +

        await client.execute(cql.KEYSPACE); creates a keyspace as defined in cql/keyspace.cql:

        +
        CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' };
        +
        +
        +

        The CQL query above creates a new keyspace named carepet, with NetworkTopologyStrategy as replication strategy and a replication factor of 3. +See Scylla University for more information about keyspaces and replication.

        +

        Finally, the code loops through all the queries listed in cql/migrate.cql to create the tables you need for the project.

        +
        CREATE TABLE IF NOT EXISTS carepet.owner
        +(
        +    owner_id UUID,
        +    address TEXT,
        +    name    TEXT,
        +    PRIMARY KEY (owner_id)
        +);
        +
        +...
        +
        +
        +

        You can check the database structure. Connect to your local ScyllaDB instance using:

        +

        docker exec -it carepet-scylla1 cqlsh

        +

        With Scylla Cloud, use:

        +
        docker run -it --rm --entrypoint cqlsh scylladb/scylla -u [USERNAME] -p [PASSWORD] [NODE-IP]
        +
        +
        +

        Once connected to your machine, run the following commands:

        +
        cqlsh> USE carepet;
        +cqlsh:carepet> DESCRIBE TABLES
        +cqlsh:carepet> DESCRIBE TABLE pet
        +
        +
        +

        You should expect the following result:

        +
        CREATE TABLE carepet.pet (
        +    owner_id uuid,
        +    pet_id uuid,
        +    chip_id text,
        +    species text,
        +    breed   text,
        +    color   text,
        +    gender  text,
        +    address text,
        +    age int,
        +    name text,
        +    weight float,
        +    PRIMARY KEY (owner_id, pet_id)
        +) WITH CLUSTERING ORDER BY (pet_id ASC)
        +    AND bloom_filter_fp_chance = 0.01
        +    AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
        +    AND comment = ''
        +    AND compaction = {'class': 'SizeTieredCompactionStrategy'}
        +    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
        +    AND crc_check_chance = 1.0
        +    AND dclocal_read_repair_chance = 0.1
        +    AND default_time_to_live = 0
        +    AND gc_grace_seconds = 864000
        +    AND max_index_interval = 2048
        +    AND memtable_flush_period_in_ms = 0
        +    AND min_index_interval = 128
        +    AND read_repair_chance = 0.0
        +    AND speculative_retry = '99.0PERCENTILE';
        +
        +
        +
        +
        +
        +

        Sensor

        +

        The sensor service simulates the collar’s activity and periodically saves data to the database. Use the below commands to run the sensor service:

        +
        +

        Using ScyllaDB on your local machine

        +
        NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +npm run sensor -- --hosts $NODE1 --measure 5s --buffer-interval 1m
        +
        +
        +
        +
        +

        Using Scylla Cloud

        +
        npm run sensor -- --hosts [NODE-IP] --username [USERNAME] --password [PASSWORD] --measure 5s --buffer-interval 1m
        +
        +
        +

        Replace the NODE-IP, USERNAME, and PASSWORD with the information provided in your cluster on https://cloud.scylladb.com.

        +

        Expected output:

        +
        2020/08/06 16:44:33 Welcome to the Pet collar simulator
        +2020/08/06 16:44:33 New owner # 9b20764b-f947-45bb-a020-bf6d02cc2224
        +2020/08/06 16:44:33 New pet # f3a836c7-ec64-44c3-b66f-0abe9ad2befd
        +2020/08/06 16:44:33 sensor # 48212af8-afff-43ea-9240-c0e5458d82c1 type L new measure 51.360596 ts 2020-08-06T16:44:33+02:00
        +2020/08/06 16:44:33 sensor # 2ff06ffb-ecad-4c55-be78-0a3d413231d9 type R new measure 36 ts 2020-08-06T16:44:33+02:00
        +2020/08/06 16:44:33 sensor # 821588e0-840d-48c6-b9c9-7d1045e0f38c type L new measure 26.380281 ts 2020-08-06T16:44:33+02:00
        +...
        +
        +
        +

        The above command executes cmd/sensor/index.js and takes the following as arguments:

        +
          +
        • hosts : the IP address of the ScyllaDB node.

        • +
        • username: when Password Authentication enabled

        • +
        • password: when Password Authentication enabled

        • +
        • measure: the interval between to sensor measures.

        • +
        • buffer-interval: the interval between two database queries.

        • +
        +
        // sensor/index.js
        +
        +async function main() {
        +  // Parse command arguments
        +  const options = cli(config('sensor simulator'))
        +    .parse()
        +    .opts();
        +
        +  const bufferInterval = parseDuration(options.bufferInterval);
        +  const measure = parseDuration(options.measure);
        +
        +  // ...
        +  
        +  // Connect to cluster using a keyspace
        +  const client = await getClientWithKeyspace(options);
        +
        +  // Generate random owner, pet and sensors IDs
        +  const { owner, pet, sensors } = randomData();
        +
        +  await saveData(client, owner, pet, sensors);
        +
        +  // Generate sensor data and save them to the database periodically
        +  await runSensorData(
        +    client,
        +    {
        +      bufferInterval,
        +      measure,
        +    },
        +    sensors
        +  );
        +
        +  return client;
        +}
        +
        +
        +

        Just like in migrate/index.js, the function parses the npm run sensor command arguments. +Now you can create a new session client using carepet keyspace.

        +
        // db.js
        +
        +async function getClientWithKeyspace(config) {
        +  return getClient(config, KEYSPACE);
        +}
        +
        +
        +

        The saveData method connects to the database and saves random owner, pet, and sensors to the database.

        +
        // sensor/index.js
        +
        +async function saveData(client, owner, pet, sensors) {
        +  await client.execute(insertQuery(Owner), owner, { prepare: true });
        +  log.info(`New owner # ${owner.owner_id}`);
        +
        +  await client.execute(insertQuery(Pet), pet, { prepare: true });
        +  log.info(`New pet # ${pet.pet_id}`);
        +
        +  for (let sensor of sensors) {
        +    await client.execute(insertQuery(Sensor), sensor, { prepare: true });
        +    log.info(`New sensor # ${sensor.sensor_id}`);
        +  }
        +}
        +
        +
        +

        The runSensorData generates random data and inserts it to the database every buffer_interval. Note that we are inserting the data to the database using a batch.

        +
        async function runSensorData(client, { bufferInterval, measure }, sensors) {
        +  let last = moment();
        +  while (true) {
        +    const measures = [];
        +    while (moment().diff(last) < bufferInterval) {
        +      await delay(measure);
        +
        +      measures.push(
        +        ...sensors.map(sensor => {
        +          const measure = readSensorData(sensor);
        +          log.info(
        +            `sensor # ${sensor.sensor_id} type ${sensor.type} new measure ${
        +              measure.value
        +            } ts ${moment(measure.ts).toISOString()}`
        +          );
        +
        +          return measure;
        +        })
        +      );
        +    }
        +
        +    last = last.add(
        +      measure.valueOf() * (moment().diff(last).valueOf() / measure.valueOf())
        +    );
        +
        +    log.info('Pushing data');
        +
        +    const batch = measures.map(measure => ({
        +      query: insertQuery(Measure),
        +      params: measure,
        +    }));
        +
        +    await client.batch(batch, { prepare: true });
        +  }
        +}
        +
        +
        +
        +
        +
        +

        Server

        +

        The server service is a REST API for tracking the pets’ health state. The service allows you to query the database via HTTP.

        +

        Run the following commands to start the server:

        +
        +

        Using ScyllaDB on your local machine

        +
        NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +npm run dev -- --hosts $NODE1
        +
        +
        +
        +
        +

        Using Scylla Cloud

        +
        npm run dev -- --hosts [NODE-IP] --username [USERNAME] --password [PASSWORD]
        +
        +
        +

        Expected output:

        +
        2020/08/06 16:45:58 Serving care pet at http://127.0.0.1:8000
        +
        +
        +

        The src/index.js main function mounts the api on /api and defines the routes.

        +
        // src/index.js
        +
        +async function main() {
        +  const options = config('care-pet').parse().opts();
        +
        +  log.debug(`Configuration = ${JSON.stringify(options)}`);
        +
        +  const client = await getClientWithKeyspace(options);
        +
        +  app.get(owner.ROUTE, asyncHandler(owner.handler(client)));
        +  app.get(pets.ROUTE, asyncHandler(pets.handler(client)));
        +  app.get(sensors.ROUTE, asyncHandler(sensors.handler(client)));
        +  app.get(measures.ROUTE, asyncHandler(measures.handler(client)));
        +  app.get(avg.ROUTE, asyncHandler(avg.handler(client)));
        +
        +  app.listen(8000, () => {
        +    log.info('Care-pet server started on port 8000!');
        +  });
        +}
        +
        +
        +
        +
        +
        +

        Using the Application

        +

        Open a different terminal to send an HTTP request from the CLI:

        +

        curl -v http://127.0.0.1:8000/

        +

        Expected output:

        +
        > GET / HTTP/1.1
        +> Host: 127.0.0.1:8000
        +> User-Agent: curl/7.71.1
        +> Accept: */*
        +> 
        +* Mark bundle as not supporting multiuse
        +< HTTP/1.1 404 Not Found
        +< Content-Type: application/json
        +< Date: Thu, 06 Aug 2020 14:47:41 GMT
        +< Content-Length: 45
        +< Connection: close
        +< 
        +* Closing connection 0
        +{"code":404,"message":"path / was not found"}
        +
        +
        +

        The JSON with the 404 at the end indicates expected behavior. +To read an owner’s data use the previously saved owner_id as follows:

        +

        curl -v http://127.0.0.1:8000/api/owner/{owner_id}

        +

        For example:

        +

        curl http://127.0.0.1:8000/api/owner/a05fd0df-0f97-4eec-a211-cad28a6e5360

        +

        Expected result:

        +
        {"address":"home","name":"gmwjgsap","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360"} 
        +
        +
        +

        To list the owner’s pets, run:

        +

        curl -v http://127.0.0.1:8000/api/owner/{owner_id}/pets

        +

        For example:

        +

        curl http://127.0.0.1:8000/api/owner/a05fd0df-0f97-4eec-a211-cad28a6e5360/pets

        +

        Expected output:

        +

        [{"address":"home","age":57,"name":"tlmodylu","owner_id":"a05fd0df-0f97-4eec-a211-cad28a6e5360","pet_id":"a52adc4e-7cf4-47ca-b561-3ceec9382917","weight":5}]

        +

        To list each pet’s sensor, run:

        +

        curl -v curl -v http://127.0.0.1:8000/api/pet/{pet_id}/sensors

        +

        For example:

        +

        curl http://127.0.0.1:8000/api/pet/cef72f58-fc78-4cae-92ae-fb3c3eed35c4/sensors

        +
        [{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d","type":"L"},{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"5c70cd8a-d9a6-416f-afd6-c99f90578d99","type":"R"},{"pet_id":"cef72f58-fc78-4cae-92ae-fb3c3eed35c4","sensor_id":"fbefa67a-ceb1-4dcc-bbf1-c90d71176857","type":"L"}]
        +
        +
        +

        To review the data from a specific sensor:

        +

        curl http://127.0.0.1:8000/api/sensor/{sensor_id}/values?from=2006-01-02T15:04:05Z07:00&to=2006-01-02T15:04:05Z07:00

        +

        For example:

        +

        curl http://127.0.0.1:8000/api/sensor/5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d/values\?from\="2020-08-06T00:00:00Z"\&to\="2020-08-06T23:59:59Z"

        +

        expected output:

        +

        [51.360596,26.737432,77.88015,...]

        +

        To read the pet’s daily average per sensor, use:

        +

        curl http://127.0.0.1:8000/api/sensor/{sensor_id}/values/day/{date}

        +

        For example:

        +

        curl -v http://127.0.0.1:8000/api/sensor/5a9da084-ea49-4ab1-b2f8-d3e3d9715e7d/values/day/2020-08-06

        +

        Expected output:

        +

        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,42.55736]

        +
        +
        +

        Resources

        + +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/build-with-php.html b/stable/build-with-php.html new file mode 100644 index 00000000..5d1eca75 --- /dev/null +++ b/stable/build-with-php.html @@ -0,0 +1,970 @@ + + + + + + + + + + + + + Care Pet ScyllaDB PHP IoT example | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Care Pet ScyllaDB PHP IoT example

        +

        This example project demonstrates a generic IoT use case for ScyllaDB in PHP.

        +

        Here you will find a list of possible drivers to integrate with.

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

        PHP Version

        Driver

        PHP 7.1

        DataStax PHP Driver

        PHP 8.2 [x]

        ScyllaDB PHP Driver (community)

        +

        You will need to build the driver following the instructions of each repository. We strongly recommend that you go for +PHP 8.x since this project still being maintained and developed by community itself.

        +

        The documentation for this application and the guided exercise is here.

        +
        +

        Quick Start

        +

        The application allows the tracking of the pets health indicators and it consist in a CLI of three parts:

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

        Command

        Description

        php scylla migrate

        creates the carepet keyspace and tables

        php scylla simulate

        generates a pet health data and pushes it into the storage

        php scylla serve

        REST API service for tracking pets health state

        +

        Prerequisites:

        + +
        +
        +

        Setup

        +

        To run a local ScyllaDB cluster consisting of three nodes and the PHP Environment with +the help of docker and docker-compose execute:

        +
        $ docker-compose up -d
        +
        +
        +

        Docker-compose will spin up three nodes which are:

        +
          +
        • carepet-scylla1

        • +
        • carepet-scylla2

        • +
        • carepet-scylla3

        • +
        +

        If you want to see your containers running, run the docker ps command, and you should see something like this:

        +
        $ docker ps
        +CONTAINER ID   IMAGE                    COMMAND                  CREATED       STATUS       PORTS                                                                      NAMES
        +4e351dfe3987   scylladb/scylla          "/docker-entrypoint.…"   1 minute ago   Up 1 minute   22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp   carepet-scylla2
        +9e7e4d3992df   scylladb/scylla          "/docker-entrypoint.…"   1 minute ago   Up 1 minute   22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp   carepet-scylla3
        +7e2b1b94389b   scylladb/scylla          "/docker-entrypoint.…"   1 minute ago   Up 1 minute   22/tcp, 7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp, 9180/tcp, 10000/tcp   carepet-scylla1
        +
        +
        +
        +

        If you have any error regarding “premature connection”, restart your docker instance and wait a minute until +your ScyllaDB connection be established.

        +
        +
        +

        Useful Commands

        +

        Here’s a list of everything that you can execute and make your own research through the application.

        +
        +

        PHP Application Commands

        +

        These commands you can execute by entering the container or through docker exec remotely:

        +
        +
        Configuring the Environment
        +

        Make a copy of .env.example and name it .env. This file will store your application secrets.

        +
        $ cp .env.example .env
        +
        +
        +

        By default, the config to connect on your local ScyllaDB instances will be ready to use.

        +
        # Development
        +DB_KEYSPACE="carepet"
        +DB_NODES="localhost"
        +DB_USERNAME=""
        +DB_PASSWORD=""
        +DB_PORT=9042
        +
        +# Production (Cloud)
        +#DB_KEYSPACE="carepet"
        +#DB_NODES="node-0.aws_sa_east_1.c106d1ac5f3117a20bf0.clusters.scylla.cloud"
        +#DB_USERNAME="scylla"
        +#DB_PASSWORD="p50bonFq8cuxwXS"
        +#DB_PORT=9042
        +
        +
        +
        +

        If you want to use ScyllaDB Cloud, remember to change at your keyspace the Replication Factor related to +for each environment.

        +
        +
        +
        +
        Initializing Keyspace:
        +

        First, let’s create our keyspace using CQLSH.

        +
        $ docker exec -it carepet-scylla1 cqlsh
        +Connected to  at 10.10.5.2:9042.
        +[cqlsh 5.0.1 | Cassandra 3.0.8 | CQL spec 3.3.1 | Native protocol v4]
        +Use HELP for help.
        +cqlsh> CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '2' };
        +cqlsh>
        +
        +
        +

        Then you can run the CLI command to migrate all your tables inside the keyspace.

        +
        $ php scylla migrate
        +[INFO] Fetching Migrations... 
        +[INFO] Migrated: /var/www/migrations/1-create_keyspace.cql 
        +[INFO] Migrated: /var/www/migrations/2-create_owner_table.cql 
        +[INFO] Migrated: /var/www/migrations/3-create_pets_table.cql 
        +[INFO] Migrated: /var/www/migrations/4-create_sensors_table.cql 
        +[INFO] Migrated: /var/www/migrations/5-create_measurements_table.cql 
        +[INFO] Migrated: /var/www/migrations/6-create_sensor_avg_table.cql 
        +[INFO] Done :D 
        +
        +
        +
        +
        +
        Starting Web Server:
        +
        $ php scylla serve
        +[INFO] CarePet Web started!
        +[INFO] Development Server: http://0.0.0.0:8000
        +[Thu Jan  5 17:32:01 2023] PHP 7.4.33 Development Server (http://0.0.0.0:8000) started
        +
        +
        +
        +
        +
        Simulate Environment Sensors:
        +
        $ php scylla simulate
        +[INFO] Starting Sensor simulator... 
        +[INFO] Batch: 0
        +[INFO] Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1 
        +[INFO] Pet: 14d9f304-5600-34af-8622-3d4505d617d7 | Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1
        +[INFO] Sensor: 869bd01e-e0ba-364f-bbfb-8c7c496a3318 (R) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
        +[INFO] Sensor: c86f63b0-1439-3404-8750-b71b90a685cb (L) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
        +[INFO] Sensor: e0550426-8832-3d17-9025-77726b3009c5 (P) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
        +[INFO] Sensor: bf960c81-8e0f-3012-b50d-18596b50db18 (P) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
        +[INFO] Sensor: 933245de-812e-34e4-8d50-2ab072726217 (T) | Pet 14d9f304-5600-34af-8622-3d4505d617d7 
        +[INFO] Pet: 319ec566-d6b0-3868-ac5e-76253ee7c236 | Owner 593dec12-6bea-3c93-8f49-26d8b6d589b1
        +[INFO] ...
        +
        +
        +
        final class SimulateCommand extends AbstractCommand
        +{
        +
        +    public function __construct(
        +        private readonly OwnerRepository $ownerRepository,
        +        private readonly PetRepository    $petRepository,
        +        private readonly SensorRepository $sensorRepository
        +    )
        +    {
        +    }
        +
        +    const AMOUNT_BASE = 50000;
        +
        +    public function __invoke(array $args = []): int
        +    {
        +        $this->info('Starting Sensor simulator...');
        +        foreach (range(0, self::AMOUNT_BASE) as $i) {
        +            $this->info("Batch: " . $i);
        +            [$ownerDTO, $petsDTO] = $this->generateFakeData();
        +
        +            $this->ownerRepository->create($ownerDTO);
        +            $this->info(sprintf('Owner %s', $ownerDTO->id));
        +
        +            $petsDTO->each(function ($petDTO) {
        +                $this->info(sprintf('Pet: %s | Owner %s', $petDTO->id->uuid(), $petDTO->ownerId));
        +                $this->petRepository->create($petDTO);
        +
        +                SensorFactory::makeMany(5, ['pet_id' => $petDTO->id])
        +                    ->each($this->handleSensors());
        +            });
        +        }
        +        $this->info('Done :D');
        +
        +        return self::SUCCESS;
        +    }
        +
        +    private function generateFakeData(): array
        +    {
        +        $ownerDTO = OwnerFactory::make();
        +        $petsDTO = PetFactory::makeMany(5, ['owner_id' => $ownerDTO->id]);
        +
        +        return [$ownerDTO, $petsDTO];
        +    }
        +
        +    private function handleSensors(): Closure
        +    {
        +        return function (SensorDTO $sensorDTO) {
        +            $this->sensorRepository->create($sensorDTO);
        +            $this->info(sprintf(
        +                'Sensor: %s (%s) | Pet %s',
        +                $sensorDTO->id,
        +                $sensorDTO->type->name,
        +                $sensorDTO->petId
        +            ));
        +        };
        +    }
        +}
        +
        +
        +
        +
        +
        Inserting Data
        +

        You can use Cassandra::cluster() and setup your cluster.

        +
        use Cassandra;
        +use Cassandra\Cluster;
        +use Cassandra\Cluster\Builder;
        +use Cassandra\FutureRows;
        +use Cassandra\Session;
        +use Cassandra\SimpleStatement;
        +
        +class Connector
        +{
        +    public Builder $connectionBuilder;
        +    public Cluster $cluster;
        +    public Session $session;
        +    public SimpleStatement $query;
        +
        +    const BASE_TIMEOUT = 10;
        +
        +    public function __construct(array $config)
        +    {
        +        $this->connectionBuilder = Cassandra::cluster()
        +            ->withContactPoints($config['nodes'])
        +            ->withDefaultConsistency($config['consistency_level'])
        +            ->withPort($config['port']);
        +
        +        if (!empty($config['username'] && !empty($config['password']))) {
        +            $this->connectionBuilder = $this->connectionBuilder->withCredentials($config['username'], $config['password']);
        +        }
        +        $this->cluster = $this->connectionBuilder->build();
        +
        +        $this->session = $this->cluster->connect($config['keyspace']);
        +    }
        +
        +    public function setKeyspace(string $keyspace = ''): self
        +    {
        +        $this->session->close(self::BASE_TIMEOUT);
        +        $this->session = $this->cluster->connect($keyspace);
        +
        +        return $this;
        +    }
        +
        +    public function prepare(string $query): self
        +    {
        +        $this->query = new SimpleStatement($query);
        +
        +        return $this;
        +    }
        +
        +    public function execute(): FutureRows
        +    {
        +        return $this->session->executeAsync($this->query, []);
        +    }
        +}
        +
        +
        +
        use App\Core\Entities\AbstractDTO;
        +use Cassandra\Rows;
        +
        +abstract class AbstractRepository
        +{
        +    public string $table = '';
        +
        +    public string $primaryKey = '';
        +
        +    public Connector $connection;
        +
        +    public array $keys = [];
        +
        +    public function __construct(Connector $connector)
        +    {
        +        $this->connection = $connector;
        +    }
        +
        +    public function getById(string $id): Rows
        +    {
        +        $query = sprintf("SELECT * FROM %s WHERE %s = %s", $this->table, $this->primaryKey, $id);
        +
        +        return $this->connection
        +            ->prepare($query)
        +            ->execute()
        +            ->get(Connector::BASE_TIMEOUT);
        +    }
        +
        +    public function all(): Rows
        +    {
        +        return $this->connection
        +            ->prepare(sprintf('SELECT * FROM %s', $this->table))
        +            ->execute()
        +            ->get(Connector::BASE_TIMEOUT);
        +    }
        +
        +    public function create(AbstractDTO $dto): void
        +    {
        +        $keys = array_keys($dto->toDatabase());
        +        $dataValues = array_values($dto->toDatabase());
        +
        +        foreach ($dataValues as $key => $value) {
        +            if (is_string($value) && !in_array($keys[$key], $this->keys)) {
        +                $value = addslashes($value);
        +                $dataValues[$key] = "'$value'";
        +            }
        +        }
        +
        +        $query = sprintf(
        +            "INSERT INTO %s (%s) VALUES (%s)",
        +            $this->table,
        +            implode(', ', $keys),
        +            implode(', ', $dataValues)
        +        );
        +
        +
        +        $this->connection
        +            ->prepare($query)
        +            ->execute();
        +    }
        +}
        +
        +
        +
        +
        +
        +

        ScyllaDB Commands

        +
        +
        Running Nodetool:
        +
        $ docker exec -it carepet-scylla1 nodetool status
        +=======================
        +Datacenter: datacenter1
        +=======================
        +Status=Up/Down
        +|/ State=Normal/Leaving/Joining/Moving
        +--  Address    Load       Tokens       Owns    Host ID                               Rack
        +UN  10.10.5.2  212 KB     256          ?       f6121e15-48df-4b31-b725-3ad2795b8b94  rack1
        +UN  10.10.5.3  1.06 MB    256          ?       871795f3-67d2-47ba-83ef-15714b89c02a  rack1
        +UN  10.10.5.4  1.06 MB    256          ?       cbe74a63-2cf4-41c2-bf7f-c831c0d2689f  rack1
        +
        +
        +
        +
        +
        Running Container Shell:
        +
        $ docker exec -it carepet-scylla1 bash
        +
        +   _____            _ _       _____  ____
        +  / ____|          | | |     |  __ \|  _ \
        + | (___   ___ _   _| | | __ _| |  | | |_) |
        +  \___ \ / __| | | | | |/ _` | |  | |  _ <
        +  ____) | (__| |_| | | | (_| | |__| | |_) |
        + |_____/ \___|\__, |_|_|\__,_|_____/|____/
        +               __/ |
        +              |___/
        +Nodetool:
        +        nodetool help
        +CQL Shell:
        +        cqlsh
        +More documentation available at:
        +        http://www.scylladb.com/doc/
        +
        +root@7e2b1b94389b:/#
        +
        +
        +
        +
        +
        Inspecting a Container
        +

        You can inspect any node by means of the docker inspect command as follows. For example:

        +
        $ docker inspect carepet-scylla1
        +[
        +    {
        +        "Id": "7e2b1b94389b36c494093db8e119c2b8c5167339f20e03d9bfa070e8e46f8430",
        +        "Created": "2023-01-05T17:36:59.038609825Z",
        +        "Path": "/docker-entrypoint.py",
        +        "Args": [
        +            "--smp",
        +            "1"
        +        ],
        +        "State": {
        +            "Status": "running",
        +            "Running": true,
        +            "Paused": false,
        +            "Restarting": false
        +            ...
        +        }
        +    }
        +]
        +
        +
        +
        +
        Get Node IP Address:
        +
        $ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1
        +10.10.5.2
        +
        +
        +
        +
        +
        +
        +
        +

        Resources

        + +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/build-with-python.html b/stable/build-with-python.html new file mode 100644 index 00000000..9b43f1dc --- /dev/null +++ b/stable/build-with-python.html @@ -0,0 +1,778 @@ + + + + + + + + + + + + + Build an IoT App with Python | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Build an IoT App with Python

        +
        +

        Architecture

        +

        This section will walk through and explain the code for the different commands. +As explained in the Getting Started page, the project is structured as follow:

        +
          +
        • Migrate (python src/migrate.py) - creates keyspace and tables in ScyllaDB

        • +
        • Sensor (python src/sensor.py) - generates random IoT data and inserts it into ScyllaDB

        • +
        • API (python src/api.py) - REST API service to fetch data from ScyllaDB

        • +
        +
        +
        +

        Clone repository and install dependencies

        +

        Clone the repository and open the root directory of the project:

        +
        git clone https://github.com/scylladb/care-pet
        +cd care-pet/python
        +
        +
        +

        Create a new virtual environment and activate it:

        +
        virtualenv env
        +source env/bin/activate
        +
        +
        +

        Install all Python dependencies:

        +
        pip install -r requirements.txt
        +
        +
        +
        +
        +

        Start Docker containers (skip this if you use Scylla Cloud)

        +

        Spin up a local ScyllaDB cluster with three nodes using docker and docker-compose:

        +
        docker-compose up -d
        +
        +Creating carepet-scylla3 ... done
        +Creating carepet-scylla2 ... done
        +Creating carepet-scylla1 ... done
        +
        +
        +

        This command starts three ScyllaDB nodes in containers:

        +
          +
        • carepet-scylla1

        • +
        • carepet-scylla2

        • +
        • carepet-scylla3

        • +
        +

        You can inspect any of these nodes by using the docker inspect command, +for example:

        +
        docker inspect carepet-scylla1
        +
        +[
        +    {
        +        "Id": "c87128b7d0ca4a31a84da78875c8b4181283c34783b6b0a78bffbacbbe45fcc2",
        +        "Created": "2023-01-08T21:17:13.212585687Z",
        +        "Path": "/docker-entrypoint.py",
        +        "Args": [
        +            "--smp",
        +            "1"
        +        ],
        +        "State": {
        +            "Status": "running",
        +            "Running": true,
        +...
        +
        +
        +
        +
        +

        Connect to ScyllaDB and create the database schema

        +

        To connect to your ScyllaDB storage within the container, you need to know the +IP address of one of the running nodes. +This is how you can get the IP address of the first node running in the container:

        +
        docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1
        +
        +
        +

        You will need to reference this value multiple times later so if it’s easier +for you can save it as a variable NODE1:

        +
        NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +
        +
        +

        Now you can run the migration script that creates the required keyspace and tables:

        +
        python src/migrate.py -h $NODE1
        +
        +Creating keyspace...
        +Done.
        +Migrating database...
        +Done.
        +
        +
        +

        See the database schema using cqlsh in the container:

        +
        docker exec -it carepet-scylla1 cqlsh
        +cqlsh> DESCRIBE KEYSPACES;
        +
        +carepet        system_auth  system_distributed_everywhere  system_traces
        +system_schema  system       system_distributed 
        +
        +cqlsh> USE carepet;
        +cqlsh:carepet> DESCRIBE TABLES;
        +
        +owner  pet  sensor  sensor_avg  measurement
        +
        +cqlsh:carepet> DESCRIBE TABLE pet;
        +
        +CREATE TABLE carepet.pet (
        +    owner_id uuid,
        +    pet_id uuid,
        +    address text,
        +    age int,
        +    name text,
        +    weight float,
        +    PRIMARY KEY (owner_id, pet_id)
        +) WITH CLUSTERING ORDER BY (pet_id ASC)
        +    AND bloom_filter_fp_chance = 0.01
        +    AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
        +    AND comment = ''
        +    AND compaction = {'class': 'SizeTieredCompactionStrategy'}
        +    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
        +    AND crc_check_chance = 1.0
        +    AND dclocal_read_repair_chance = 0.0
        +    AND default_time_to_live = 0
        +    AND gc_grace_seconds = 864000
        +    AND max_index_interval = 2048
        +    AND memtable_flush_period_in_ms = 0
        +    AND min_index_interval = 128
        +    AND read_repair_chance = 0.0
        +    AND speculative_retry = '99.0PERCENTILE';
        +
        +cqlsh:carepet> exit;
        +
        +
        +

        At this point you have ScyllaDB running with the correct keyspace and tables.

        +
        +
        +

        Generate and ingest IoT data

        +

        Start ingesting IoT data (it’s suggested to do this in a new separate terminal +because this process runs indefinitely). Make sure you’re still in the virtual +environment:

        +
        source env/bin/activate
        +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +python src/sensor.py -h $NODE1 --measure 2 --buffer-interval 10
        +
        +Welcome to the Pet collar simulator
        +New owner # 1cfbc0e5-6b05-476d-b170-2660cf40c02a
        +New pet # 1a0800ee-7643-4794-af7b-2ecaaf7078fc
        +New sensor(0) # b6155934-bd4e-47de-8649-1fad447aa036
        +New sensor(1) # d2c62c4d-9621-469d-b62c-41ef2271fca7
        +sensor # b6155934-bd4e-47de-8649-1fad447aa036 type T, new measure: 100.55118431400851, ts: 2023-01-08 17:36:17.126374
        +sensor # d2c62c4d-9621-469d-b62c-41ef2271fca7 type L, new measure: 37.486651732296835, ts: 2023-01-08 17:36:17.126516
        +
        +
        +

        This command starts a script that generates and ingests random IoT data coming +from two sensors every other second and inserts the data in batches +every ten seconds. Whenever you see Pushing data in the command line that is +when data actually gets insterted into ScyllaDB.

        +

        Optional: You can modify the frequency of the generated data by changing the +--measure and --buffer-interval arguments. For example, +you can generate new data points every three seconds and insert the batches +every 30 seconds:

        +
        source env/bin/activate
        +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +python src/sensor.py -h $NODE1 --measure 3 --buffer-interval 30
        +
        +
        +

        You can run multiple ingestion processes in parallel if you wish.

        +
        +
        +

        Set up and test REST API

        +

        In a new terminal, start running the API server (make sure that port 8000 is free):

        +
        source env/bin/activate
        +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +python src/api.py -h $NODE1
        +
        +INFO:     Started server process [696274]
        +INFO:     Waiting for application startup.
        +INFO:     Application startup complete.
        +INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
        +
        +
        +

        The API server is running on http://127.0.0.1:8000. Test with your +browser, or curl, if it works properly:

        +
        curl http://127.0.0.1:8000
        +
        +{"message":"Pet collar simulator API"}
        +
        +
        +

        Next, you will test the following API endpoints:

        +
          +
        • /api/owner/{owner_id}

          +

          Returns all available data fields about the owner.

          +
        • +
        • /api/owner/{owner_id}/pets

          +

          Returns the owner’s pets.

          +
        • +
        • /api/pet/{pet_id}/sensors

          +

          Returns all the sensors of a pet.

          +
        • +
        +

        To test these endpoints, you need to provide either an owner_id or a pet_id +as URL path parameter. You can get these values by copying them from the +beginning of output of the ingestion script:

        +
        source env/bin/activate
        +NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +python src/sensor.py -h $NODE1 --measure 1 --buffer-interval 6
        +
        +Welcome to the Pet collar simulator
        +New owner # 1cfbc0e5-6b05-476d-b170-2660cf40c02a <-- This is what you need!
        +New pet # 1a0800ee-7643-4794-af7b-2ecaaf7078fc <-- This is what you need!
        +New sensor(0) # b6155934-bd4e-47de-8649-1fad447aa036
        +New sensor(1) # d2c62c4d-9621-469d-b62c-41ef2271fca7
        +
        +
        +

        Copy the UUID values right after “New owner #” and “New pet #”. A UUID value +looks like this:

        +
        1cfbc0e5-6b05-476d-b170-2660cf40c02a
        +
        +
        +

        /api/owner/{owner_id}

        +

        Paste the owner id from the terminal into the endpoint URL and open it with +your browser or use curl, for example:

        +
        curl http://127.0.0.1:8000/api/owner/4f42fb80-c209-4d19-8c43-daf554f1be23
        +
        +{"owner_id":"4f42fb80-c209-4d19-8c43-daf554f1be23","address":"home","name":"Vito Russell"}
        +
        +
        +

        /api/owner/{owner_id}/pets

        +

        Use the same owner id value to test this endpoint, for example:

        +
        curl http://127.0.0.1:8000/api/owner/4f42fb80-c209-4d19-8c43-daf554f1be23/pets
        +
        +[{"owner_id":"4f42fb80-c209-4d19-8c43-daf554f1be23","pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","address":"home","age":20,"name":"Duke","weight":14.41481876373291}]
        +
        +
        +

        /api/pet/{pet_id}/sensors

        +

        Finally, use a pet id to test this endpoint, for example:

        +
        curl http://127.0.0.1:8000/api/pet/44f1624e-07c2-4971-85a5-85b9ad1ff142/sensors
        +
        +[{"pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","sensor_id":"4bb1d214-712b-453b-b53a-ac5d4df4a1f8","type":"T"},{"pet_id":"44f1624e-07c2-4971-85a5-85b9ad1ff142","sensor_id":"e81915d6-1155-45e4-9174-c58e4cb8cecf","type":"L"}]
        +
        +
        +
        +
        +

        Resources

        + +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/build-with-rust.html b/stable/build-with-rust.html new file mode 100644 index 00000000..30b596c5 --- /dev/null +++ b/stable/build-with-rust.html @@ -0,0 +1,914 @@ + + + + + + + + + + + + + Build an IoT App with Rust | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Build an IoT App with Rust

        +
        +

        Architecture

        +

        This section will walk through and explain the code for the different commands. +As explained in the Getting Started page, the project is structured as follow:

        +
          +
        • migrate (/bin/migrate/main.rs) - creates the carepet keyspace and tables

        • +
        • collar (/bin/sensor/main.rs) - generates a pet health data and pushes it into the storage

        • +
        • web app (/main.rs) - REST API service for tracking pets health state

        • +
        +
        +
        +

        Migrate

        +

        Start by creating a local ScyllaDB cluster consisting of 3 nodes:

        +
        docker-compose up -d
        +
        +
        +

        Docker-compose will spin up a ScyllaDB cluster consisting of 3 nodes (carepet-scylla1, carepet-scylla2 and carepet-scylla3) along with the app (for example go-app) container. Wait for about two minutes and check the status of the cluster: To check the status of the cluster:

        +
        docker exec -it carepet-scylla1 nodetool status
        +
        +
        +

        Once all the nodes are in UN - Up Normal status, run the below commands:

        +

        The below command allows you to get node IP address:

        +
        docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1
        +
        +
        +

        The run the following commands to execute the migrate main function.

        +
        NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +cargo run --bin migrate -- --hosts $NODE1
        +
        +
        +

        The command executes the main function in the bin/migrate/main.rs. The function creates the keyspace and tables that you need to run the collar and server services.

        +

        The below code in the bin/migrate/main.rs creates a new session then calls the create_keyspace , migrate functions.

        +
        // migrate/main.rs
        +
        +async fn main() -> Result<()> {
        +    care_pet::log::init();
        +
        +    let app = App::from_args();
        +    debug!("Configuration = {:?}", app);
        +
        +    info!("Bootstrapping database...");
        +
        +    let sess = db::new_session(&app.db_config).await?;
        +
        +    db::create_keyspace(&sess).await?;
        +    db::migrate(&sess).await?;
        +
        +    Ok(())
        +}
        +
        +
        +

        The new_session function takes the config as a parameter and uses SessionBuilder class to crete a new session.

        +
        // db/mod.rs
        +
        +pub async fn new_session(config: &Config) -> Result<Session> {
        +    info!("Connecting to {}", config.hosts.join(", "));
        +
        +    SessionBuilder::new()
        +        .known_nodes(&config.hosts)
        +        .connection_timeout(config.timeout.into())
        +        .user(
        +            config.username.clone().unwrap_or_default(),
        +            config.password.clone().unwrap_or_default(),
        +        )
        +        .build()
        +        .await
        +        .map_err(From::from)
        +}
        +
        +
        +

        For more information about creating a new session with the Rust Driver, please have a look at the docs.

        +

        create_keyspace function takes a session as an argument and creates a keyspace as defined in db/keyspace.cql:

        +
        CREATE KEYSPACE IF NOT EXISTS carepet WITH replication = { 'class': 'NetworkTopologyStrategy', 'replication_factor': '3' };
        +
        +
        +

        The CQL query above creates a new keyspace named carepet, with NetworkTopologyStrategy as replication strategy and a replication factor of 3. +More information about keyspace and replication on Scylla University.

        +

        Finally, migrate will execute the queries listed in db/migrate.cql to create the tables you need for the project.

        +
        CREATE TABLE IF NOT EXISTS carepet.owner
        +(
        +    owner_id UUID,
        +    address TEXT,
        +    name    TEXT,
        +    PRIMARY KEY (owner_id)
        +);
        +
        +...
        +
        +
        +

        You can check the database structure with:

        +
        docker exec -it carepet-scylla1 cqlsh
        +cqlsh> USE carepet;
        +cqlsh:carepet> DESCRIBE TABLES
        +cqlsh:carepet> DESCRIBE TABLE pet
        +
        +
        +

        You should expect the following result:

        +
        CREATE TABLE carepet.pet (
        +    owner_id uuid,
        +    pet_id uuid,
        +    chip_id text,
        +    species text,
        +    breed   text,
        +    color   text,
        +    gender  text,
        +    address text,
        +    age int,
        +    name text,
        +    weight float,
        +    PRIMARY KEY (owner_id, pet_id)
        +) WITH CLUSTERING ORDER BY (pet_id ASC)
        +    AND bloom_filter_fp_chance = 0.01
        +    AND caching = {'keys': 'ALL', 'rows_per_partition': 'ALL'}
        +    AND comment = ''
        +    AND compaction = {'class': 'SizeTieredCompactionStrategy'}
        +    AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
        +    AND crc_check_chance = 1.0
        +    AND dclocal_read_repair_chance = 0.1
        +    AND default_time_to_live = 0
        +    AND gc_grace_seconds = 864000
        +    AND max_index_interval = 2048
        +    AND memtable_flush_period_in_ms = 0
        +    AND min_index_interval = 128
        +    AND read_repair_chance = 0.0
        +    AND speculative_retry = '99.0PERCENTILE';
        +
        +
        +
        +
        +

        Sensor

        +

        The sensor service simulates the collar’s activity and periodically saves data to the database. Use the below commands to run the sensor service:

        +
        NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +cargo run --bin sensor -- --hosts $NODE1 --measure 5s --buffer-interval 1m
        +
        +
        +

        The above command executes bin/sensor/main.rs and and takes the following as arguments.

        +
          +
        • hosts : the IP address of the ScyllaDB node.

        • +
        • measure: the interval between to sensor measures.

        • +
        • buffer-interval: the interval between two database queries.

        • +
        +
        // sensor/main.rs
        +
        +#[tokio::main]
        +async fn main() -> Result<()> {
        +    care_pet::log::init();
        +
        +    let app = App::from_args();
        +    debug!("Configuration = {:?}", &app);
        +
        +    info!("Welcome to the Pet collar simulator");
        +
        +    let sess = db::new_session_with_keyspace(&app.db_config).await?;
        +
        +    let (owner, pet, sensors) = random_data();
        +    save_data(&sess, &owner, &pet, &sensors).await?;
        +    run_sensor_data(&app, &sess, sensors).await?;
        +
        +    Ok(())
        +}
        +
        +
        +

        The app object contains the command’s arguments listed above. +We then create a new session sess using new_session_with_keyspace function defined in db/mod.rs:

        +
        // db/mod.rs
        +
        +pub async fn new_session_with_keyspace(config: &Config) -> Result<Session> {
        +    let session = new_session(config).await?;
        +    session.use_keyspace(KEYSPACE, true).await?;
        +    Ok(session)
        +}
        +
        +
        +

        The save_data method connects to the datbase and saves random owner, pet and the sensors to the database using insert_query macro defined in src/mod.rs.

        +
        // sensor/main.rs
        +
        +async fn save_data(sess: &Session, owner: &Owner, pet: &Pet, sensors: &[Sensor]) -> Result<()> {
        +    sess.query(insert_query!(Owner), owner).await?;
        +    info!("New owner # {}", owner.owner_id);
        +
        +    sess.query(insert_query!(Pet), pet).await?;
        +    info!("New pet # {}", pet.pet_id);
        +
        +    for sensor in sensors {
        +        sess.query(insert_query!(Sensor), sensor).await?;
        +    }
        +
        +    Ok(())
        +}
        +
        +
        +

        The run_sensor_data generates random data and inserts it to the database every buffer_interval.

        +
        async fn run_sensor_data(cfg: &App, sess: &Session, sensors: Vec<Sensor>) -> Result<()> {
        +    let measure: time::Duration = cfg.measure.into();
        +    let buffer_interval: time::Duration = cfg.buffer_interval.into();
        +
        +    let mut last = Instant::now();
        +    loop {
        +        let mut measures = vec![];
        +        while last.elapsed() < buffer_interval {
        +            sleep(measure).await;
        +
        +            for sensor in &sensors {
        +                let measure = read_sensor_data(sensor);
        +                info!(
        +                    "sensor # {} type {} new measure {} ts {}",
        +                    sensor.sensor_id,
        +                    sensor.r#type.as_str(),
        +                    &measure.value,
        +                    measure.ts.format_rfc3339(),
        +                );
        +
        +                measures.push(measure);
        +            }
        +        }
        +
        +        last = last
        +            + time::Duration::from_nanos(
        +                (measure.as_nanos() * (last.elapsed().as_nanos() / measure.as_nanos())) as u64,
        +            );
        +
        +        info!("Pushing data");
        +
        +        let batch = measures.iter().fold(Batch::default(), |mut batch, _| {
        +            batch.append_statement(insert_query!(Measure));
        +            batch
        +        });
        +
        +        sess.batch(&batch, measures)
        +            .await
        +            .map_err(|err| error!("execute batch query {:?}", err))
        +            .ok();
        +    }
        +}
        +
        +
        +
        +
        +

        Server

        +

        The server service is a REST API for tracking the pets’ health state. The service was built using Rocket and allows users to query the database via HTTP.

        +

        Run the following commands to start the server:

        +
        NODE1=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' carepet-scylla1)
        +cargo run -- --hosts $NODE1
        +
        +
        +

        The src/main.rs main function mounts the api on /api and defines the routes.

        +
        // src/main.rs
        +
        +#[rocket::main]
        +async fn main() -> Result<()> {
        +    care_pet::log::init();
        +
        +    let app = App::from_args();
        +    if app.verbose {
        +        info!("Configuration = {:?}", app);
        +    }
        +
        +    let sess = db::new_session_with_keyspace(&app.db_config).await?;
        +
        +    rocket::build()
        +        .mount(
        +            "/api",
        +            routes![
        +                handler::measures::find_sensor_data_by_sensor_id_and_time_range,
        +                handler::owner::find_owner_by_id,
        +                handler::pets::find_pets_by_owner_id,
        +                handler::sensors::find_sensors_by_pet_id,
        +                handler::avg::find_sensor_avg_by_sensor_id_and_day
        +            ],
        +        )
        +        .manage(sess)
        +        .launch()
        +        .await
        +        .map_err(From::from)
        +}
        +
        +
        +

        The handlers can be found in the src/handler folder for each route.

        +

        Let’s have a look at handler/mesure.rs file:

        +
        #[get("/sensor/<id>/values?<from>&<to>")]
        +pub async fn find_sensor_data_by_sensor_id_and_time_range(
        +    session: &State<Session>,
        +    id: UuidParam,
        +    from: DateTimeParam,
        +    to: DateTimeParam,
        +) -> Result<Json<Vec<f32>>, JsonError> {
        +    let rows = session
        +        .query(
        +            format!(
        +                "SELECT {} FROM {} WHERE {} = ? and {} >= ? and {} <= ?",
        +                Measure::FIELD_NAMES.value,
        +                Measure::table(),
        +                Measure::FIELD_NAMES.sensor_id,
        +                Measure::FIELD_NAMES.ts,
        +                Measure::FIELD_NAMES.ts,
        +            ),
        +            (id.0, from.0, to.0),
        +        )
        +        .await
        +        .map_err(|err| json_err(Status::InternalServerError, err))?
        +        .rows
        +        .unwrap_or_default()
        +        .into_typed::<(f32,)>();
        +
        +    let values = rows
        +        .map(|v| v.map(|v| v.0))
        +        .collect::<Result<Vec<_>, _>>()
        +        .map_err(|err| json_err(Status::InternalServerError, err))?;
        +
        +    Ok(Json(values))
        +}
        +
        +
        +

        The GET request on URL /sensor/<id>/values?<from>&<to> triggers find_sensor_data_by_sensor_id_and_time_range function.

        +

        find_sensor_data_by_sensor_id_and_time_range takes session, id, from and to as params. The function runs a SELECT query then returns rows.

        +
        +
        +

        Retrieving informations from API

        +

        To test out the API in your terminal, use the following command to retrieve informations of a specific pet owner:

        +
        curl http://127.0.0.1:8000/owner/{id}
        +
        +
        +
        +

        If you don’t have an owner_id, run the sensor command and it will generate users and pets on your terminal.

        +
        +

        and you should receive a response similar to this:

        +
        {
        +  "owner_id": "5b5a7b4d-a2c0-48b0-91e1-de6a5b37c923",
        +  "address": "home",
        +  "name": "sedtdkaa"
        +}
        +
        +
        +

        If you want to list owner’s pets you can use the following command:

        +
        curl http://127.0.0.1:8000/owner/{id}/pets
        +
        +
        +

        and you should receive a response similar to this:

        +
        [
        +  {
        +    "owner_id": "5b5a7b4d-a2c0-48b0-91e1-de6a5b37c923",
        +    "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999",
        +    "chip_id": null,
        +    "species": "dog",
        +    "breed": "golden-retriever",
        +    "color": "black",
        +    "gender": "M",
        +    "age": 4,
        +    "weight": 9.523097,
        +    "address": "awesome-address",
        +    "name": "doggo"
        +  }
        +]
        +
        +
        +

        If you want to list the active pet sensors you can use the following command:

        +
        curl http://127.0.0.1:8000/pet/{pet_id}/sensors
        +
        +
        +

        and you should receive a response similar to this:

        +
        [
        +  {
        +    "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999",
        +    "sensor_id": "7a8b3831-0512-4501-90f2-700c7133aeed",
        +    "type": "T"
        +  },
        +  {
        +    "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999",
        +    "sensor_id": "81250bab-cf1c-4c7a-84f1-b291a0f325ef",
        +    "type": "P"
        +  },
        +  {
        +    "pet_id": "9e9facb9-3bd8-4451-b179-8c951cdf0999",
        +    "sensor_id": "a22a2fdb-4aad-4abe-b0d9-381aa07a26af",
        +    "type": "L"
        +  }
        +]
        +
        +
        +
        +
        +

        Resources

        + +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/deploy-in-cloud.html b/stable/deploy-in-cloud.html new file mode 100644 index 00000000..e18e219c --- /dev/null +++ b/stable/deploy-in-cloud.html @@ -0,0 +1,603 @@ + + + + + + + + + + + + + Deploy in ScyllaDB Cloud with Terraform | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Deploy in ScyllaDB Cloud with Terraform

        +

        ScyllaDB Cloud has a Terraform provider which means that you can spin up new +ScyllaDB Cloud clusters easily using Terraform. Follow the instructions below to +set up the care-pet sample application in a ScyllaDB Cloud environment using Terraform.

        +

        You’ll set up Terraform to:

        +
          +
        1. Create a new ScyllaDB Cloud cluster (you need a ScyllaDB Cloud account)

        2. +
        3. Execute a CQL file that creates a new keyspace and tables for the care-pet project

        4. +
        +
        +

        Prerequisites

        + +
        +
        +

        Get started

        +
        +

        Clone the repository

        +

        Clone the repository if you haven’t already:

        +
        git clone https://github.com/scylladb/care-pet.git
        +
        +
        +
        +
        +

        Install CQLSH

        +

        Install the standalone CQLSH Python package:

        +
        pip install cqlsh
        +
        +
        +

        This package will be used to connect to ScyllaDB and create the initial schema.

        +
        +
        +

        Spin up a new ScyllaDB Cloud cluster

        +

        Go to the terraform directory and run terraform init

        +
        cd terraform/
        +terraform init
        +
        +
        +

        Apply the changes that are configured in the main.tf file:

        +
        terraform apply
        +
        +
        +

        You’ll be asked to provide your ScyllaDB Cloud API token (more info in docs):

        +
        var.scylla_api_token
        +  Your own ScyllaDB Cloud API token
        +
        +  Enter a value:
        +
        +
        +

        You’ll also be asked if you want to perform the actions configured in Terraform, just type yes:

        +
        Do you want to perform these actions?
        +  Terraform will perform the actions described above.
        +  Only 'yes' will be accepted to approve.
        +
        +  Enter a value: yes
        +
        +  scylladbcloud_cluster.care_pet: Creating...
        +
        +
        +

        Spinning up the cluster takes about ~10 minutes. While the process is underway, you can go to your +ScyllaDB Cloud dashboard and verify that the cluster is getting set up:

        +

        cluster setting up

        +

        After the process is completed, go to the “Connect” tab in in the cloud console +and connect to your newly created cluster with your favourite tool.

        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/design-and-data-model.html b/stable/design-and-data-model.html new file mode 100644 index 00000000..fcbcb043 --- /dev/null +++ b/stable/design-and-data-model.html @@ -0,0 +1,686 @@ + + + + + + + + + + + + + Design and Data Model | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Design and Data Model

        +

        You can learn more about Data Modeling in Scylla (and NoSQL) by taking +this course on Scylla +University. The main goal of data modeling in Scylla is to perform queries fast, +even if we sometimes have to duplicate data.

        +

        Let’s build our schema around the queries we are going to run against our domain +entities. When creating the data model, you need to consider both the conceptual +data model and the application workflow: which queries will be performed by +which users and how often.

        +

        To achieve that, we want:

        +
          +
        • Even data distribution

        • +
        • To minimize the number of partitions accessed in a read query.

        • +
        +

        On the other hand, our focus won’t be on avoiding data duplication or minimizing +the number of writes. You’re probably familiar with the steps defined here:

        +

        +
        +

        Conceptual Data Model

        +

        Starting with the conceptual data model, we need to identify the key entities +and the relationships between them. Our application has pets. Each dog can be +tracked by many followers (typically the owners). A follower can also track more +than one dog. Each dog can have a few sensors. Each sensor takes measurements:

        +

        +
        +
        +

        Application Workflow

        +

        Next, we move on to the Application Workflow. In this part, we identify the main +queries or what questions we will ask the database. This part is important in +Scylla, and other NoSQL databases and, as opposed to relational databases is +performed early on in the data modeling process. Remember that our data modeling +is built around the queries.

        +

        +
        +
        +

        Queries

        +

        Now we can detail the above queries in +CQL:

        +

        Q1: Find a Follower with a specific ID

        +
        SELECT * FROM owner WHERE owner_id = ?
        +
        +
        +

        Q2: Find the pets that the follower tracks

        +
        SELECT * FROM pet WHERE owner_id = ?
        +
        +
        +

        Q3: Find the sensors of a pet

        +
        SELECT * FROM sensor WHERE pet_id = ?
        +
        +
        +

        Q4: Find the measurements for a sensor in a date range

        +
        SELECT * FROM measurements WHERE sensor_id = ? AND ts <= ? and ts >= ?;
        +
        +
        +

        Q5: Find a daily summary of hour based aggregates

        +
        SELECT * FROM sensor_avg WHERE sensor_id = ? AND date = ? ORDER BY date ASC, hour ASC;
        +
        +
        +
        +
        +

        Logical Data Model

        +

        Using the outcomes of the application workflow and the conceptual data model, we +can now create the logical data model. At this stage, we determine how our +tables will look and which fields will be used as primary and clustering keys. +Selecting a primary key and clustering key is highly important, you can learn +more about it in +this lesson. +Remember that in Scylla, it’s better to duplicate data than to join, see more +about denormalization in +this lesson.

        +

        +
        +
        +

        Physical Data Model

        +

        In this part, we take the Logical Data Model above and add CQL data types. Make +sure you’re familiar with the ScyllaDB (and Cassandra for that matter) +data types +before proceeding.

        +

        Based on the high availability requirements, we will use a +replication factor +(RF) of three. The RF is defined when we create the +Keyspace, +as we will see later on. Choosing the compaction strategy is explained +here +and in this +University Lesson. For the tables sensor_avg and measurement, we will use the +Time Window Compaction Strategy (TWCS).

        +

        The reason is those tables contain time-series data. The “measurement” table +stores sensor measurements, and the “sensor_avg” stores aggregated hourly +averages. For such data, there is an optimized compaction strategy TWCS based on +the Size Tiered Compaction Strategy with the fair assumption that the data at +different time slots will never overlap. That isolates buckets compaction +in-between the time windows into independent units reducing overall compaction +write amplification. For the other tables, we will use the default +compaction strategy, +Size Tiered Compaction Strategy (STCS). +Remember that if you are using Scylla Enterprise, you should +probably be using Incremental Compaction Strategy (ICS) +as it offers better performance. We can now define the tables below, according +to the physical data model.

        +
        CREATE TABLE IF NOT EXISTS owner (
        +    owner_id UUID,
        +    address TEXT,
        +    name    TEXT,
        +    PRIMARY KEY (owner_id)
        +);
        +
        +CREATE TABLE IF NOT EXISTS pet (
        +    owner_id UUID,
        +    pet_id   UUID,
        +    chip_id  TEXT,
        +    species  TEXT,
        +    breed    TEXT,
        +    color    TEXT,
        +    gender   TEXT,
        +    age     INT,
        +    weight  FLOAT,
        +    address TEXT,
        +    name    TEXT,
        +    PRIMARY KEY (owner_id, pet_id)
        +);
        +
        +CREATE TABLE IF NOT EXISTS sensor (
        +    pet_id UUID,
        +    sensor_id UUID,
        +    type TEXT,
        +    PRIMARY KEY (pet_id, sensor_id)
        +);
        +
        +CREATE TABLE IF NOT EXISTS measurement (
        +    sensor_id UUID,
        +    ts       TIMESTAMP,
        +    value    FLOAT,
        +    PRIMARY KEY (sensor_id, ts)
        +) WITH compaction = { 'class' : 'TimeWindowCompactionStrategy' };
        +
        +CREATE TABLE IF NOT EXISTS sensor_avg (
        +    sensor_id UUID,
        +    date    DATE,
        +    hour    INT,
        +    value   FLOAT,
        +    PRIMARY KEY (sensor_id, date, hour)
        +) WITH compaction = { 'class' : 'TimeWindowCompactionStrategy' };
        +
        +
        +

        Some more advanced topics not covered in this guide are +Collections, +User-DefinedTypes +(UDT), expiring data with time to live (TTL), +and Counters.

        +

        To summarize, when data modeling with Scylla, we have to know our data, think +about our queries, pay attention to the primary key and clustering key +selection, and not be afraid to duplicate data.

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/genindex.html b/stable/genindex.html new file mode 100644 index 00000000..d50e4c43 --- /dev/null +++ b/stable/genindex.html @@ -0,0 +1,499 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + + + +
        + + + + + +
        + + +
        + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/getting-started.html b/stable/getting-started.html new file mode 100644 index 00000000..78891ba6 --- /dev/null +++ b/stable/getting-started.html @@ -0,0 +1,659 @@ + + + + + + + + + + + + + Getting Started with CarePet: A sample IoT App | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Getting Started with CarePet: A sample IoT App

        +
        +

        Introduction

        +

        This guide will show you how to create an IoT app from scratch and configure it +to use Scylla as the backend datastore. It’ll walk you through all the stages +of the development process, from gathering requirements to building and running +the application.

        +

        As an example, you will use an application called CarePet. CarePet allows pet +owners to track their pets’ health by monitoring their key health parameters, +such as temperature or pulse. The application consists of three parts:

        +
          +
        • A pet collar with sensors that collects pet health data and sends the data to the datastore.

        • +
        • A web app for reading the data and analyzing the pets’ health.

        • +
        • A database migration module.

        • +
        +

        You can use this example with minimal changes for any IoT application.

        +
        +
        +

        Architecture

        +
          +
        • migrate - Creates the CarePet keyspace and tables.

        • +
        • sensor - Generates pet health data and pushes it into storage.

        • +
        • server - REST API service for tracking the pets’ health state.

        • +
        +

        Build your first ScyllaDB Powered App - Raouf

        +
        +
        +

        Requirements

        +
        +

        Prerequisites for Deploying the Application

        +

        The example application uses Docker to run a three-node ScyllaDB cluster. You can also use Scylla Cloud as your database. +Claim your free Scylla Cloud account here.

        +
        +
        +

        Use Case Requirements

        +

        Each pet collar has sensors that report four different measurements: +temperature, pulse, location, and respiration.

        +

        The collar reads the measurements from the sensors once per second +and sends the data directly to the app.

        +
        +
        +

        Performance Requirements

        +

        The application has two performance-related parts: sensors that write to +the database (throughput sensitive) and a backend dashboard that reads from +the database (latency sensitive).

        +
          +
        • This example assumes 99% writes (sensors) and 1% reads (backend dashboard).

        • +
        • SLA:

          +
            +
          • Writes: throughput of 100K operations per second.

          • +
          • Reads: latency of up to 10 milliseconds for the +99th percentile.

          • +
          +
        • +
        • The application requires high availability and fault tolerance. Even if a +ScyllaDB node goes down or becomes unavailable, the cluster is expected to +remain available and continue to provide service. You can learn more about +Scylla high availability in this lesson.

        • +
        +
        +
        +
        +

        Deploying the Application in ScyllaDB Cloud

        +

        Using the ScyllaDB Cloud Terraform provider, you can easily spin up new ScyllaDB Cloud clusters. Complete this tutorial quicker by creating a new t3.micro cluster (the smallest instance) in ScyllaDB Cloud. Go to Deploy in ScyllaDB Cloud with Terraform for instructions.

        +
        +
        +

        Deploying the Application Locally

        +
          +
        1. Check out the care-pet repository from GitHub and go to the directory of +the language you want to use (Go, Java, etc.):

          +
          git clone git@github.com:scylladb/care-pet.git
          +cd care-pet/go
          +
          +
          +
        2. +
        3. Create a local ScyllaDB cluster consisting of three nodes:

          +
          docker-compose up -d
          +
          +
          +

          Docker-compose will spin up a ScyllaDB cluster consisting of three nodes: +carepet-scylla1, carepet-scylla2 and carepet-scylla3. The process will +take about two minutes.

          +
        4. +
        5. Check the status of the cluster:

          +
          docker exec -it carepet-scylla1 nodetool status
          +
          +
          +
        6. +
        7. Continue by following the instructions for the programming language you’re using. See Build the Application with Your Programming Language.

        8. +
        +
        +
        +

        Build the Application with Your Programming Language

        + +
        +
        +

        Additional Resources

        + +

        Future Work

        +
          +
        • Add Sizing

        • +
        • Add Benchmarking

        • +
        • Add Python implementation

        • +
        • In a real-world application, it would be better to aggregate data in an internal buffer and send it once a day to the application gateway in a batch, implying techniques such as delta encoding. It could also aggregate data at a lower resolution and take measurements less frequently. The collar could notify the pet’s owner about suspicious health parameters directly or via the application.

        • +
        • Add location tracking info to send alerts when the pet enters/leaves safe zones using known WiFi networks.

        • +
        • Use the measurements to present to the pet owner health alerts, vital signs, sleeping levels, activity levels, and calories burned.

        • +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/index.html b/stable/index.html new file mode 100644 index 00000000..aec951a0 --- /dev/null +++ b/stable/index.html @@ -0,0 +1,618 @@ + + + + + + + + + + + + + Scylla Care-Pet Example | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/objects.inv b/stable/objects.inv new file mode 100644 index 00000000..2ad88597 Binary files /dev/null and b/stable/objects.inv differ diff --git a/stable/search.html b/stable/search.html new file mode 100644 index 00000000..99db6ba6 --- /dev/null +++ b/stable/search.html @@ -0,0 +1,502 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + + + +
        + + + + + +
        + + +
        + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/searchindex.js b/stable/searchindex.js new file mode 100644 index 00000000..b19ce308 --- /dev/null +++ b/stable/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["build-with-go", "build-with-java", "build-with-javascript", "build-with-php", "build-with-python", "build-with-rust", "deploy-in-cloud", "design-and-data-model", "getting-started", "index"], "filenames": ["build-with-go.md", "build-with-java.md", "build-with-javascript.md", "build-with-php.md", "build-with-python.md", "build-with-rust.md", "deploy-in-cloud.md", "design-and-data-model.md", "getting-started.md", "index.rst"], "titles": ["Build an IoT App with Go", "Build an IoT App with Java", "Build an IoT App with JavaScript", "Care Pet ScyllaDB PHP IoT example", "Build an IoT App with Python", "Build an IoT App with Rust", "Deploy in ScyllaDB Cloud with Terraform", "Design and Data Model", "Getting Started with CarePet: A sample IoT App", "Scylla Care-Pet Example"], "terms": {"In": [0, 1, 2, 4, 7, 8], "thi": [0, 1, 2, 3, 5, 6, 7, 8, 9], "section": [0, 1, 2, 4, 5], "we": [0, 1, 2, 3, 5, 7], "walk": [0, 1, 2, 4, 5, 8, 9], "you": [0, 1, 2, 3, 5, 6, 7, 8, 9], "through": [0, 1, 2, 3, 4, 5, 8, 9], "carepet": [0, 1, 2, 3, 4, 5], "command": [0, 1, 2, 4, 5], "explain": [0, 1, 2, 4, 5, 7, 8], "code": [0, 1, 4, 5], "behind": [0, 1, 2], "them": [0, 1, 2, 4, 7], "As": [0, 4, 5, 8], "get": [0, 1, 2, 4, 5, 9], "start": [0, 1, 5, 7, 9], "project": [0, 1, 2, 3, 4, 5, 6, 9], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "structur": [0, 1, 4, 5], "follow": [0, 1, 2, 3, 4, 5, 6, 7, 8], "cmd": [0, 2], "creat": [0, 1, 2, 3, 5, 6, 7, 8, 9], "keyspac": [0, 1, 2, 4, 5, 6, 7, 8], "tabl": [0, 1, 2, 3, 4, 5, 6, 7, 8], "collar": [0, 1, 2, 4, 5, 8], "simul": [0, 1, 2, 4, 5], "pet": [0, 1, 2, 4, 5, 6, 7, 8, 9], "": [0, 1, 2, 3, 4, 5, 7, 8], "gener": [0, 1, 2, 3, 5, 8], "health": [0, 1, 2, 3, 5, 8], "data": [0, 1, 2, 5, 8, 9], "push": [0, 1, 2, 3, 4, 5, 8], "storag": [0, 1, 2, 3, 4, 5, 8], "rest": [0, 1, 2, 3, 5, 8], "api": [0, 1, 2, 3, 6, 8], "servic": [0, 1, 2, 3, 4, 5, 8, 9], "track": [0, 1, 2, 3, 5, 7, 8], "state": [0, 1, 2, 3, 4, 5, 8], "The": [0, 1, 2, 3, 4, 5, 7, 8, 9], "us": [0, 1, 5, 6, 7, 9], "line": [0, 1, 4], "25": 0, "27": [0, 1], "file": [0, 1, 3, 5, 6], "call": [0, 1, 2, 5, 8], "createkeyspac": [0, 1], "migratekeyspac": 0, "printkeyspacemetadata": 0, "function": [0, 1, 2, 3, 5], "func": 0, "main": [0, 1, 2, 5, 6, 7], "new": [0, 1, 2, 3, 4, 5, 8, 9], "session": [0, 1, 2, 3, 5], "execut": [0, 1, 2, 3, 5, 6], "cql": [0, 1, 2, 3, 5, 6, 7], "queri": [0, 1, 2, 3, 5, 8, 9], "store": [0, 1, 3, 7], "db": [0, 2, 5], "IF": [0, 1, 2, 3, 5, 7], "NOT": [0, 1, 2, 3, 5, 7], "exist": [0, 1, 2, 3, 5, 7], "WITH": [0, 1, 2, 3, 4, 5, 7], "replic": [0, 1, 2, 3, 5, 7], "class": [0, 1, 2, 3, 4, 5, 7], "networktopologystrategi": [0, 1, 2, 3, 5], "replication_factor": [0, 1, 2, 3, 5], "3": [0, 1, 2, 3, 4, 5], "AND": [0, 1, 2, 4, 5, 7], "durable_writ": [0, 1], "true": [0, 1, 2, 3, 4, 5], "se": 0, "err": [0, 5], "config": [0, 1, 2, 3, 5], "nil": 0, "log": [0, 1, 2, 5], "fatalln": 0, "defer": 0, "close": [0, 2, 3], "check": [0, 1, 2, 5, 8], "error": [0, 3, 5], "keyspacecql": 0, "exec": [0, 1, 2, 3, 4, 5, 8], "ensur": 0, "open": [0, 1, 2, 4], "locat": [0, 1, 2, 8], "care": [0, 1, 2, 4, 6, 8, 9], "ddl": [0, 1], "owner": [0, 1, 2, 3, 4, 5, 7, 8], "measur": [0, 1, 2, 4, 5, 7, 8], "sensor_avg": [0, 1, 2, 4, 7], "om": 0, "context": 0, "background": 0, "name": [0, 1, 2, 3, 4, 5, 7], "suggest": [0, 4], "print": [0, 1], "metadata": [0, 1, 2], "relat": [0, 1, 3, 7, 8], "confirm": [0, 1], "were": 0, "properli": [0, 1, 4], "activ": [0, 1, 2, 3, 4, 5, 8], "struct": 0, "its": 0, "defin": [0, 1, 2, 5, 7], "along": [0, 5], "sensortyp": [0, 1], "save": [0, 1, 2, 4, 5], "databas": [0, 1, 2, 5, 7, 8, 9], "newpet": 0, "println": 0, "p": [0, 2, 3, 5], "ownerid": [0, 3], "petid": [0, 3], "run": [0, 1, 4, 5, 6, 7, 8], "allow": [0, 1, 2, 3, 5, 8], "user": [0, 2, 5, 7, 8], "via": [0, 1, 2, 5, 8], "http": [0, 1, 2, 3, 4, 5, 6], "exampl": [0, 1, 2, 4, 5, 8, 9], "curl": [0, 1, 2, 4, 5], "127": [0, 1, 2, 4, 5], "0": [0, 1, 2, 3, 4, 5], "1": [0, 1, 2, 3, 4, 5, 8], "8000": [0, 1, 2, 3, 4, 5], "id": [0, 1, 2, 3, 4, 5, 7], "expect": [0, 1, 2, 5, 8], "respons": [0, 1, 5], "address": [0, 1, 2, 4, 5, 7], "home": [0, 1, 2, 4, 5], "ag": [0, 1, 2, 4, 5, 7], "57": [0, 1, 2], "tlmodylu": [0, 1, 2], "owner_id": [0, 1, 2, 3, 4, 5, 7], "a05fd0df": [0, 1, 2], "0f97": [0, 1, 2], "4eec": [0, 1, 2], "a211": [0, 1, 2], "cad28a6e5360": [0, 1, 2], "pet_id": [0, 1, 2, 3, 4, 5, 7], "a52adc4": [0, 1, 2], "7cf4": [0, 1, 2], "47ca": [0, 1, 2], "b561": [0, 1, 2], "3ceec9382917": [0, 1, 2], "weight": [0, 1, 2, 4, 5, 7], "5": [0, 1, 2, 3, 5], "let": [0, 1, 2, 3, 5, 7], "first": [0, 1, 3, 4], "discuss": 0, "from": [0, 2, 3, 4, 7, 8, 9], "23": 0, "28": 0, "oper": [0, 8], "newcarepetapi": 0, "spec": [0, 2, 3], "restapi": 0, "newserv": 0, "shutdown": 0, "configur": [0, 2, 5, 6, 8, 9], "configureapi": 0, "object": [0, 1, 5], "repres": 0, "list": [0, 1, 2, 3, 5], "swagger": 0, "tool": [0, 6], "those": [0, 7], "ar": [0, 1, 2, 3, 5, 6, 7], "pass": [0, 1], "method": [0, 1, 2, 5], "handler": [0, 2, 5], "One": 0, "findownerbyid": 0, "gocqlx": 0, "findownerbyidhandlerfunc": 0, "return": [0, 1, 2, 3, 4, 5], "param": [0, 2, 5], "findownerbyidparam": 0, "middlewar": 0, "respond": 0, "var": [0, 3, 6], "model": [0, 1, 2, 8, 9], "tableown": 0, "getqueri": 0, "bind": [0, 1], "string": [0, 1, 3], "getreleas": 0, "gocql": [0, 2], "errnotfound": 0, "findownerbyiddefault": 0, "statu": [0, 2, 3, 4, 5, 8], "404": [0, 2], "newfindownerbyiddefault": 0, "statusnotfound": 0, "els": 0, "find": [0, 3, 7], "500": 0, "statusinternalservererror": 0, "200": 0, "inform": [0, 1, 2, 8, 9], "findownerbyidok": 0, "payload": 0, "conv": 0, "uuid": [0, 1, 2, 3, 4, 5, 7], "strfmt": 0, "result": [0, 1, 2, 5], "throw": 0, "found": [0, 2, 5], "32": [0, 3], "scylladb": [0, 1, 5, 7, 9], "driver": [0, 1, 2, 3, 4, 5], "github": [0, 1, 2, 3, 4, 5, 6, 8], "univers": [0, 1, 2, 4, 5, 7, 8], "scylla": [0, 1, 3, 5, 7, 8, 9], "document": [0, 1, 3, 4, 5, 8], "page": [0, 4, 5], "com": [1, 2, 3, 4, 6, 8], "web": [1, 2, 5, 8], "bin": [1, 4, 5], "sh": 1, "host": [1, 2, 3, 5], "node1": [1, 2, 4, 5], "datacent": [1, 3], "datacenter1": [1, 2, 3], "createschema": 1, "printmetadata": 1, "public": [1, 3], "static": 1, "void": [1, 3], "arg": [1, 3, 4], "final": [1, 2, 3, 4, 5], "pars": [1, 2], "client": [1, 2], "break": [1, 2], "down": [1, 2, 3, 8], "argument": [1, 2, 4, 5], "our": [1, 3, 7], "case": [1, 3], "ip": [1, 2, 4, 5], "one": [1, 4, 7], "node": [1, 2, 4, 5, 8], "default": [1, 3, 5, 7], "could": [1, 8], "differ": [1, 2, 4, 5, 7, 8], "cloud": [1, 3, 9], "also": [1, 6, 7, 8], "accept": [1, 2, 6], "usernam": [1, 2, 3, 5], "password": [1, 2, 3, 5], "requir": [1, 2, 4, 7], "cqlsession": 1, "info": [1, 2, 3, 4, 5, 6, 8], "try": 1, "connect": [1, 2, 3, 5, 6, 9], "getresourc": 1, "abov": [1, 2, 5, 6, 7], "strategi": [1, 2, 5, 7], "factor": [1, 2, 3, 5, 7], "see": [1, 2, 3, 4, 7, 8], "more": [1, 2, 3, 5, 6, 7, 8, 9], "about": [1, 2, 4, 5, 6, 7, 8, 9], "split": 1, "can": [1, 2, 3, 4, 5, 6, 7, 8], "docker": [1, 2, 3, 5, 8], "scylla1": [1, 2, 3, 4, 5, 8], "cqlsh": [1, 2, 3, 4, 5], "describ": [1, 2, 4, 5, 6], "should": [1, 2, 3, 5, 7], "chip_id": [1, 2, 5, 7], "text": [1, 2, 4, 5, 7], "speci": [1, 2, 5, 7], "breed": [1, 2, 5, 7], "color": [1, 2, 5, 7], "gender": [1, 2, 5, 7], "int": [1, 2, 3, 4, 5, 7], "float": [1, 2, 4, 5, 7], "primari": [1, 2, 4, 5, 7, 9], "kei": [1, 2, 3, 4, 5, 7, 8, 9], "cluster": [1, 2, 3, 4, 5, 7, 8, 9], "order": [1, 2, 4, 5, 7], "BY": [1, 2, 4, 5, 7], "asc": [1, 2, 4, 5, 7], "bloom_filter_fp_ch": [1, 2, 4, 5], "01": [1, 2, 3, 4, 5], "cach": [1, 2, 4, 5], "all": [1, 2, 3, 4, 5, 8], "rows_per_partit": [1, 2, 4, 5], "comment": [1, 2, 4, 5], "compact": [1, 2, 4, 5, 7], "sizetieredcompactionstrategi": [1, 2, 4, 5], "compress": [1, 2, 4, 5], "sstable_compress": [1, 2, 4, 5], "org": [1, 2, 4, 5], "apach": [1, 2, 4, 5], "cassandra": [1, 2, 3, 4, 5, 7], "io": [1, 2, 4, 5], "lz4compressor": [1, 2, 4, 5], "crc_check_chanc": [1, 2, 4, 5], "dclocal_read_repair_ch": [1, 2, 4, 5], "default_time_to_l": [1, 2, 4, 5], "gc_grace_second": [1, 2, 4, 5], "864000": [1, 2, 4, 5], "max_index_interv": [1, 2, 4, 5], "2048": [1, 2, 4, 5], "memtable_flush_period_in_m": [1, 2, 4, 5], "min_index_interv": [1, 2, 4, 5], "128": [1, 2, 4, 5], "read_repair_ch": [1, 2, 4, 5], "speculative_retri": [1, 2, 4, 5], "99": [1, 2, 4, 5, 8], "0percentil": [1, 2, 4, 5], "mvn": 1, "packag": [1, 2, 6], "inspect": [1, 2, 4, 5], "f": [1, 2, 3, 4, 5], "rang": [1, 2, 3, 4, 5, 7], "networkset": [1, 2, 3, 4, 5], "network": [1, 2, 3, 4, 5, 8], "ipaddress": [1, 2, 3, 4, 5], "end": [1, 2, 3, 4, 5, 9], "pt1m": 1, "buffer": [1, 2, 4, 5, 8], "interv": [1, 2, 4, 5], "sensorconfig": 1, "instanc": [1, 2, 3, 8], "like": [1, 2, 3, 4], "constructor": 1, "random": [1, 2, 4, 5], "attribut": 1, "getownerid": 1, "valu": [1, 2, 3, 4, 5, 6, 7], "length": [1, 2], "getpetid": 1, "datbas": [1, 5], "privat": [1, 3], "mapper": 1, "m": [1, 5], "builder": [1, 3], "preparedstat": 1, "batchstatementbuild": 1, "multipl": [1, 4], "same": [1, 4], "time": [1, 4, 5, 7, 9], "doc": [1, 3, 5, 6], "stabl": 1, "manual": 1, "core": [1, 3], "statement": 1, "prepar": [1, 2, 3], "detail": [1, 7], "insert": [1, 2, 4, 5], "INTO": [1, 3], "sensor_id": [1, 2, 4, 5, 7], "t": [1, 2, 3, 4, 5, 6, 7], "batchtyp": 1, "unlog": 1, "arraylist": 1, "instant": [1, 5], "prev": 1, "now": [1, 2, 4, 5, 7], "while": [1, 2, 5, 6], "durat": [1, 5], "between": [1, 2, 5, 7], "compareto": 1, "bufferinterv": [1, 2], "sleep": [1, 5, 8], "readsensordata": [1, 2], "add": [1, 2, 7, 8, 9], "tostr": 1, "plusmilli": 1, "tomilli": 1, "simplifi": 1, "batch": [1, 2, 3, 4, 5, 8], "standard": 1, "best": 1, "practic": 1, "up": [1, 2, 3, 5, 8, 9], "partit": [1, 7], "www": [1, 3], "2019": 1, "03": 1, "applic": [1, 4, 6], "addstat": 1, "getsensorid": 1, "gett": 1, "getvalu": 1, "clearstat": 1, "clear": 1, "control": 1, "modelcontrol": 1, "implement": [1, 8], "access": [1, 2, 7], "aggreg": [1, 2, 7, 8], "saveaggreg": 1, "monoton": 1, "sequenti": 1, "sensorid": 1, "prevavgs": 1, "locald": 1, "dai": [1, 2, 8], "localdatetim": 1, "current": 1, "hour": [1, 7], "boolean": 1, "samed": 1, "getdayofyear": 1, "gethour": 1, "size": [1, 7, 8], "sensoravg": 1, "npm": 2, "dev": 2, "purpos": 2, "backend": [2, 8, 9], "instal": 2, "schema": [2, 6, 7, 9], "x": [2, 3], "orm": 2, "prerequisit": [2, 3], "nodej": 2, "test": [2, 5], "v17": 2, "v8": 2, "compos": [2, 3, 4, 5, 8], "clone": [2, 5, 8], "repositori": [2, 3, 8], "chang": [2, 3, 4, 6, 8], "directori": [2, 4, 6, 8], "git": [2, 4, 6, 8], "cd": [2, 4, 6, 8], "make": [2, 3, 4, 7, 9], "sure": [2, 4, 7], "depend": 2, "To": [2, 3, 4, 5, 7], "consist": [2, 3, 5, 8], "three": [2, 3, 4, 7, 8], "help": [2, 3], "d": [2, 3, 4, 5, 8], "spin": [2, 3, 4, 5, 8, 9], "scylla2": [2, 3, 4, 5, 8], "scylla3": [2, 3, 4, 5, 8], "nodetool": [2, 5, 8], "onc": [2, 5, 8], "un": [2, 3, 5], "normal": [2, 3, 5], "below": [2, 5, 6, 7], "If": [2, 3, 5], "replac": 2, "provid": [2, 4, 6, 8], "2020": 2, "08": [2, 4], "06": [2, 3], "16": 2, "43": 2, "bootstrap": [2, 5], "13": [2, 4], "durablewrit": 2, "strategyclass": 2, "strategyopt": 2, "map": [2, 5], "gocqlx_migr": 2, "0xc00016ca80": 2, "0xc00016cbb0": 2, "0xc00016cce0": 2, "0xc00016ce10": 2, "0xc00016cf40": 2, "0xc00016d070": 2, "type": [2, 3, 4, 5, 6, 7], "view": 2, "rm": 2, "entrypoint": [2, 3, 4], "u": 2, "note": 2, "system_schema": [2, 4], "system_auth": [2, 4], "system": [2, 4], "system_distribut": [2, 4], "system_trac": [2, 4], "exit": [2, 4], "need": [2, 3, 4, 5, 6, 7], "create_keyspac": [2, 3, 5], "async": [2, 5], "const": [2, 3], "option": [2, 4], "opt": 2, "await": [2, 5], "getclient": 2, "debug": [2, 5], "take": [2, 5, 6, 7, 8], "paramet": [2, 4, 5, 8], "src": [2, 4, 5], "contactpoint": 2, "authprovid": 2, "auth": 2, "plaintextauthprovid": 2, "localdatacent": 2, "loop": [2, 5], "With": 2, "period": [2, 5], "1m": [2, 5], "44": 2, "33": [2, 3], "welcom": [2, 4, 5], "9b20764b": 2, "f947": 2, "45bb": 2, "a020": 2, "bf6d02cc2224": 2, "f3a836c7": 2, "ec64": 2, "44c3": 2, "b66f": 2, "0abe9ad2befd": 2, "48212af8": 2, "afff": 2, "43ea": 2, "9240": 2, "c0e5458d82c1": 2, "l": [2, 3, 4, 5], "51": 2, "360596": 2, "06t16": 2, "02": 2, "00": 2, "2ff06ffb": 2, "ecad": 2, "4c55": 2, "be78": 2, "0a3d413231d9": 2, "r": [2, 3, 4, 5], "36": [2, 3, 4], "821588e0": 2, "840d": 2, "48c6": 2, "b9c9": 2, "7d1045e0f38c": 2, "26": 2, "380281": 2, "when": [2, 4, 7, 8], "authent": 2, "enabl": 2, "two": [2, 4, 5, 8], "cli": [2, 3], "parsedur": 2, "getclientwithkeyspac": 2, "randomdata": 2, "savedata": 2, "runsensordata": 2, "just": [2, 6], "insertqueri": 2, "everi": [2, 4, 5], "buffer_interv": [2, 5], "last": [2, 5], "moment": 2, "diff": 2, "delai": 2, "toisostr": 2, "valueof": 2, "45": 2, "58": 2, "serv": [2, 3], "mount": [2, 5], "rout": [2, 5], "json": [2, 5], "stringifi": 2, "asynchandl": 2, "avg": [2, 5], "listen": 2, "port": [2, 3, 4], "termin": [2, 4, 5], "send": [2, 8], "request": [2, 5], "v": [2, 5], "agent": 2, "7": [2, 3], "71": 2, "mark": 2, "bundl": 2, "support": 2, "multius": 2, "Not": 2, "content": 2, "date": [2, 7], "thu": [2, 3], "aug": 2, "14": [2, 4], "47": 2, "41": 2, "gmt": 2, "messag": [2, 4], "path": [2, 3, 4], "wa": [2, 5], "indic": [2, 3], "behavior": 2, "read": [2, 7, 8, 9], "previous": 2, "For": [2, 3, 4, 5, 7], "gmwjgsap": 2, "each": [2, 3, 5, 7, 8], "cef72f58": 2, "fc78": 2, "4cae": 2, "92ae": 2, "fb3c3eed35c4": 2, "5a9da084": 2, "ea49": 2, "4ab1": 2, "b2f8": 2, "d3e3d9715e7d": 2, "5c70cd8a": 2, "d9a6": 2, "416f": 2, "afd6": 2, "c99f90578d99": 2, "fbefa67a": 2, "ceb1": 2, "4dcc": 2, "bbf1": 2, "c90d71176857": 2, "review": 2, "specif": [2, 5, 7], "2006": 2, "02t15": 2, "04": 2, "05z07": 2, "06t00": 2, "00z": 2, "06t23": 2, "59": [2, 3], "59z": 2, "737432": 2, "77": 2, "88015": 2, "daili": [2, 7], "averag": [2, 7], "per": [2, 8], "42": 2, "55736": 2, "third": [2, 3], "parti": [2, 3], "demonstr": 3, "here": [3, 7, 8], "possibl": 3, "integr": [3, 9], "version": 3, "datastax": 3, "8": 3, "2": [3, 4], "commun": 3, "build": [3, 7, 9], "instruct": [3, 6, 8], "strongli": 3, "recommend": 3, "go": [3, 5, 6, 7, 8, 9], "sinc": 3, "still": [3, 4], "being": 3, "maintain": 3, "develop": [3, 8], "itself": 3, "guid": [3, 7, 8, 9], "exercis": 3, "part": [3, 7, 8], "descript": 3, "migrat": [3, 4, 8], "local": [3, 4, 5], "which": [3, 6, 7], "want": [3, 5, 6, 7, 8], "your": [3, 4, 5, 6], "someth": 3, "imag": 3, "4e351dfe3987": 3, "minut": [3, 5, 6, 8], "ago": 3, "22": 3, "tcp": 3, "7000": 3, "7001": 3, "7199": 3, "9042": 3, "9160": 3, "9180": 3, "10000": 3, "9e7e4d3992df": 3, "7e2b1b94389b": 3, "have": [3, 4, 5, 7], "ani": [3, 4, 8], "regard": 3, "prematur": 3, "restart": 3, "wait": [3, 4, 5], "until": 3, "establish": 3, "everyth": 3, "own": [3, 6], "research": 3, "These": 3, "enter": [3, 6, 8], "remot": 3, "copi": [3, 4], "env": [3, 4], "secret": 3, "cp": 3, "By": 3, "readi": 3, "db_keyspac": 3, "db_node": 3, "localhost": 3, "db_usernam": 3, "db_password": 3, "db_port": 3, "product": 3, "aws_sa_east_1": 3, "c106d1ac5f3117a20bf0": 3, "p50bonfq8cuxwx": 3, "rememb": [3, 7], "10": [3, 4, 6, 8], "nativ": 3, "protocol": 3, "v4": 3, "Then": 3, "insid": 3, "fetch": [3, 4], "create_owner_t": 3, "create_pets_t": 3, "4": [3, 5], "create_sensors_t": 3, "create_measurements_t": 3, "6": [3, 4], "create_sensor_avg_t": 3, "done": [3, 4], "jan": 3, "17": [3, 4], "2023": [3, 4], "593dec12": 3, "6bea": 3, "3c93": 3, "8f49": 3, "26d8b6d589b1": 3, "14d9f304": 3, "5600": 3, "34af": 3, "8622": 3, "3d4505d617d7": 3, "869bd01e": 3, "e0ba": 3, "364f": 3, "bbfb": 3, "8c7c496a3318": 3, "c86f63b0": 3, "1439": 3, "3404": 3, "8750": 3, "b71b90a685cb": 3, "e0550426": 3, "8832": 3, "3d17": 3, "9025": 3, "77726b3009c5": 3, "bf960c81": 3, "8e0f": 3, "3012": 3, "b50d": 3, "18596b50db18": 3, "933245de": 3, "812e": 3, "34e4": 3, "8d50": 3, "2ab072726217": 3, "319ec566": 3, "d6b0": 3, "3868": 3, "ac5": 3, "76253ee7c236": 3, "simulatecommand": 3, "extend": 3, "abstractcommand": 3, "__construct": 3, "readonli": 3, "ownerrepositori": 3, "petrepositori": 3, "sensorrepositori": 3, "amount_bas": 3, "50000": 3, "__invok": 3, "arrai": 3, "foreach": 3, "self": 3, "ownerdto": 3, "petsdto": 3, "generatefakedata": 3, "sprintf": 3, "petdto": 3, "sensorfactori": 3, "makemani": 3, "handlesensor": 3, "success": 3, "ownerfactori": 3, "petfactori": 3, "closur": 3, "sensordto": 3, "futurerow": 3, "simplestat": 3, "connector": 3, "connectionbuild": 3, "base_timeout": 3, "withcontactpoint": 3, "withdefaultconsist": 3, "consistency_level": 3, "withport": 3, "empti": 3, "withcredenti": 3, "setkeyspac": 3, "executeasync": 3, "app": [3, 9], "entiti": [3, 7], "abstractdto": 3, "row": [3, 5], "abstract": 3, "abstractrepositori": 3, "primarykei": 3, "getbyid": 3, "select": [3, 5, 7, 9], "where": [3, 5, 7], "dto": 3, "array_kei": 3, "todatabas": 3, "datavalu": 3, "array_valu": 3, "is_str": 3, "in_arrai": 3, "addslash": 3, "implod": 3, "leav": [3, 8], "join": [3, 5, 7], "move": [3, 7], "load": 3, "token": [3, 6], "rack": 3, "212": 3, "kb": 3, "256": 3, "f6121e15": 3, "48df": 3, "4b31": 3, "b725": 3, "3ad2795b8b94": 3, "rack1": 3, "mb": 3, "871795f3": 3, "67d2": 3, "47ba": 3, "83ef": 3, "15714b89c02a": 3, "cbe74a63": 3, "2cf4": 3, "41c2": 3, "bf7f": 3, "c831c0d2689f": 3, "bash": 3, "_____": 3, "_": [3, 5], "____": 3, "__": 3, "___": 3, "avail": [3, 4, 7, 8], "root": [3, 4], "mean": [3, 6], "7e2b1b94389b36c494093db8e119c2b8c5167339f20e03d9bfa070e8e46f8430": 3, "05t17": 3, "038609825z": 3, "py": [3, 4], "smp": [3, 4], "paus": 3, "fals": 3, "sensor": [4, 7, 8], "virtual": 4, "environ": [4, 6, 9], "virtualenv": 4, "sourc": 4, "pip": [4, 6], "txt": 4, "c87128b7d0ca4a31a84da78875c8b4181283c34783b6b0a78bffbacbbe45fcc2": 4, "08t21": 4, "212585687z": 4, "within": 4, "know": [4, 7], "how": [4, 7, 8], "refer": 4, "later": [4, 7], "so": 4, "easier": 4, "variabl": 4, "script": 4, "h": 4, "system_distributed_everywher": 4, "At": [4, 7], "point": 4, "correct": 4, "do": [4, 6], "separ": 4, "becaus": 4, "process": [4, 6, 7, 8], "indefinit": 4, "re": [4, 7, 8], "1cfbc0e5": 4, "6b05": 4, "476d": 4, "b170": 4, "2660cf40c02a": 4, "1a0800e": 4, "7643": 4, "4794": 4, "af7b": 4, "2ecaaf7078fc": 4, "b6155934": 4, "bd4e": 4, "47de": 4, "8649": 4, "1fad447aa036": 4, "d2c62c4d": 4, "9621": 4, "469d": 4, "b62c": 4, "41ef2271fca7": 4, "100": 4, "55118431400851": 4, "126374": 4, "37": 4, "486651732296835": 4, "126516": 4, "come": 4, "other": [4, 7, 8], "second": [4, 8], "ten": 4, "whenev": 4, "actual": 4, "instert": 4, "modifi": 4, "frequenc": 4, "30": 4, "parallel": 4, "wish": 4, "server": [4, 8], "free": [4, 8], "696274": 4, "startup": 4, "complet": [4, 6, 8, 9], "uvicorn": 4, "press": 4, "ctrl": 4, "c": 4, "quit": 4, "browser": 4, "work": [4, 8], "next": [4, 7], "endpoint": 4, "field": [4, 7], "either": 4, "url": [4, 5], "begin": 4, "output": 4, "what": [4, 7], "right": 4, "after": [4, 6, 9], "A": [4, 7], "look": [4, 5, 7], "past": 4, "4f42fb80": 4, "c209": 4, "4d19": 4, "8c43": 4, "daf554f1be23": 4, "vito": 4, "russel": 4, "44f1624e": 4, "07c2": 4, "4971": 4, "85a5": 4, "85b9ad1ff142": 4, "20": 4, "duke": 4, "41481876373291": 4, "4bb1d214": 4, "712b": 4, "453b": 4, "b53a": 4, "ac5d4df4a1f8": 4, "e81915d6": 4, "1155": 4, "45e4": 4, "9174": 4, "c58e4cb8cecf": 4, "contain": [5, 7], "cargo": 5, "fn": 5, "care_pet": [5, 6], "init": [5, 6], "from_arg": 5, "sess": 5, "new_sess": 5, "db_config": 5, "ok": 5, "sessionbuild": 5, "crete": 5, "mod": 5, "pub": 5, "known_nod": 5, "connection_timeout": 5, "timeout": 5, "unwrap_or_default": 5, "map_err": 5, "pleas": 5, "tokio": 5, "new_session_with_keyspac": 5, "random_data": 5, "save_data": 5, "run_sensor_data": 5, "use_keyspac": 5, "insert_queri": 5, "macro": 5, "cfg": 5, "vec": 5, "mut": 5, "elaps": 5, "read_sensor_data": 5, "as_str": 5, "format_rfc3339": 5, "from_nano": 5, "as_nano": 5, "u64": 5, "iter": 5, "fold": 5, "append_stat": 5, "built": [5, 7], "rocket": 5, "verbos": 5, "find_sensor_data_by_sensor_id_and_time_rang": 5, "find_owner_by_id": 5, "find_pets_by_owner_id": 5, "find_sensors_by_pet_id": 5, "find_sensor_avg_by_sensor_id_and_dai": 5, "manag": 5, "launch": 5, "folder": 5, "mesur": 5, "uuidparam": 5, "datetimeparam": 5, "f32": 5, "jsonerror": 5, "format": 5, "field_nam": 5, "json_err": 5, "internalservererror": 5, "into_typ": 5, "collect": [5, 7, 8], "trigger": 5, "out": [5, 8], "don": 5, "receiv": 5, "similar": 5, "5b5a7b4d": 5, "a2c0": 5, "48b0": 5, "91e1": 5, "de6a5b37c923": 5, "sedtdkaa": 5, "9e9facb9": 5, "3bd8": 5, "4451": 5, "b179": 5, "8c951cdf0999": 5, "null": 5, "dog": [5, 7], "golden": 5, "black": 5, "9": 5, "523097": 5, "awesom": 5, "doggo": 5, "7a8b3831": 5, "0512": 5, "4501": 5, "90f2": 5, "700c7133aeed": 5, "81250bab": 5, "cf1c": 5, "4c7a": 5, "84f1": 5, "b291a0f325ef": 5, "a22a2fdb": 5, "4aad": 5, "4abe": 5, "b0d9": 5, "381aa07a26af": 5, "ha": [6, 7, 8], "easili": [6, 8], "set": 6, "sampl": 6, "ll": [6, 8], "account": [6, 8], "python": [6, 8, 9], "haven": 6, "alreadi": 6, "standalon": 6, "initi": 6, "appli": 6, "tf": 6, "ask": [6, 7], "scylla_api_token": 6, "perform": [6, 7], "action": 6, "ye": 6, "onli": 6, "approv": 6, "scylladbcloud_clust": 6, "underwai": 6, "dashboard": [6, 8], "verifi": 6, "tab": 6, "consol": 6, "newli": 6, "favourit": 6, "learn": [7, 8, 9], "nosql": [7, 8, 9], "cours": [7, 8], "goal": 7, "fast": 7, "even": [7, 8], "sometim": 7, "duplic": 7, "around": 7, "against": 7, "domain": 7, "consid": 7, "both": 7, "often": 7, "achiev": 7, "distribut": 7, "minim": [7, 8], "number": 7, "On": 7, "hand": 7, "focu": 7, "won": 7, "avoid": 7, "write": [7, 8], "probabl": 7, "familiar": 7, "step": [7, 9], "identifi": 7, "relationship": 7, "mani": 7, "typic": 7, "than": 7, "few": 7, "question": 7, "import": 7, "oppos": 7, "earli": 7, "q1": 7, "q2": 7, "q3": 7, "q4": 7, "q5": 7, "summari": 7, "base": 7, "outcom": 7, "stage": [7, 8], "determin": 7, "highli": 7, "lesson": [7, 8], "better": [7, 8], "denorm": [7, 8], "matter": 7, "befor": 7, "proceed": 7, "high": [7, 8], "rf": 7, "choos": 7, "window": 7, "twc": 7, "reason": 7, "seri": 7, "hourli": 7, "an": [7, 8, 9], "optim": 7, "tier": 7, "fair": 7, "assumpt": 7, "slot": 7, "never": 7, "overlap": 7, "That": 7, "isol": 7, "bucket": 7, "independ": 7, "unit": 7, "reduc": 7, "overal": 7, "amplif": 7, "stc": 7, "enterpris": 7, "increment": 7, "ic": 7, "offer": 7, "accord": 7, "timestamp": 7, "timewindowcompactionstrategi": 7, "some": 7, "advanc": [7, 8], "topic": [7, 8], "cover": 7, "udt": 7, "expir": 7, "live": 7, "ttl": 7, "counter": 7, "summar": 7, "think": 7, "pai": 7, "attent": 7, "afraid": 7, "show": 8, "scratch": [8, 9], "datastor": [8, 9], "It": 8, "gather": 8, "monitor": 8, "temperatur": 8, "puls": 8, "analyz": 8, "modul": 8, "claim": 8, "report": 8, "four": 8, "respir": 8, "directli": 8, "throughput": 8, "sensit": 8, "latenc": [8, 9], "assum": 8, "sla": 8, "100k": 8, "millisecond": 8, "99th": 8, "percentil": 8, "fault": 8, "toler": 8, "goe": 8, "becom": 8, "unavail": 8, "remain": 8, "continu": 8, "terraform": [8, 9], "tutori": [8, 9], "quicker": 8, "t3": 8, "micro": 8, "smallest": 8, "java": [8, 9], "etc": 8, "javascript": [8, 9], "php": [8, 9], "rust": [8, 9], "essenti": 8, "basic": 8, "techniqu": 8, "includ": 8, "workflow": 8, "analysi": 8, "slack": 8, "channel": 8, "futur": 8, "benchmark": 8, "real": [8, 9], "world": 8, "would": 8, "intern": 8, "gatewai": 8, "impli": 8, "delta": 8, "encod": 8, "lower": 8, "resolut": 8, "less": 8, "frequent": 8, "notifi": 8, "suspici": 8, "alert": 8, "safe": 8, "zone": 8, "known": 8, "wifi": 8, "present": 8, "vital": 8, "sign": 8, "level": 8, "calori": 8, "burn": 8, "low": 9, "iot": 9, "abl": 9, "back": 9, "share": 9, "design": 9, "blog": 9, "addit": 9, "articl": 9, "deploi": 9}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"build": [0, 1, 2, 4, 5, 8], "an": [0, 1, 2, 4, 5], "iot": [0, 1, 2, 3, 4, 5, 8], "app": [0, 1, 2, 4, 5, 8], "go": 0, "introduct": [0, 8], "migrat": [0, 1, 2, 5], "sensor": [0, 1, 2, 3, 5], "server": [0, 1, 2, 3, 5], "resourc": [0, 1, 2, 3, 4, 5, 8], "java": 1, "architectur": [1, 2, 4, 5, 8], "javascript": 2, "code": 2, "structur": 2, "implement": 2, "quick": [2, 3], "start": [2, 3, 4, 6, 8], "us": [2, 3, 4, 8], "scylladb": [2, 3, 4, 6, 8], "your": [2, 8], "local": [2, 8], "machin": 2, "run": [2, 3], "scylla": [2, 4], "cloud": [2, 4, 6, 8], "output": 2, "index": 2, "j": 2, "applic": [2, 3, 7, 8], "care": 3, "pet": 3, "php": 3, "exampl": 3, "setup": 3, "command": 3, "configur": 3, "environ": 3, "initi": 3, "keyspac": 3, "web": 3, "simul": 3, "insert": 3, "data": [3, 4, 7], "nodetool": 3, "contain": [3, 4], "shell": 3, "inspect": 3, "get": [3, 6, 8], "node": 3, "ip": 3, "address": 3, "python": 4, "clone": [4, 6], "repositori": [4, 6], "instal": [4, 6], "depend": 4, "docker": 4, "skip": 4, "thi": 4, "you": 4, "connect": 4, "creat": 4, "databas": 4, "schema": 4, "gener": 4, "ingest": 4, "set": 4, "up": [4, 6], "test": 4, "rest": 4, "api": [4, 5], "rust": 5, "retriev": 5, "inform": 5, "from": 5, "deploi": [6, 8], "terraform": 6, "prerequisit": [6, 8], "cqlsh": 6, "spin": 6, "new": 6, "cluster": 6, "design": 7, "model": 7, "conceptu": 7, "workflow": 7, "queri": 7, "logic": 7, "physic": 7, "carepet": 8, "A": 8, "sampl": 8, "requir": 8, "case": 8, "perform": 8, "program": 8, "languag": 8, "addit": 8}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.todo": 2, "sphinx": 60}, "alltitles": {"Build an IoT App with Java": [[1, "build-an-iot-app-with-java"]], "Architecture": [[1, "architecture"], [4, "architecture"], [5, "architecture"], [2, "architecture"], [8, "architecture"]], "Migrate": [[1, "migrate"], [0, "migrate"], [5, "migrate"], [2, "migrate"]], "Sensor": [[1, "sensor"], [0, "sensor"], [5, "sensor"], [2, "sensor"]], "Server": [[1, "server"], [0, "server"], [5, "server"], [2, "server"]], "Resources": [[1, "resources"], [0, "resources"], [4, "resources"], [5, "resources"], [3, "resources"], [2, "resources"]], "Build an IoT App with Go": [[0, "build-an-iot-app-with-go"]], "Introduction": [[0, "introduction"], [8, "introduction"]], "Design and Data Model": [[7, "design-and-data-model"]], "Conceptual Data Model": [[7, "conceptual-data-model"]], "Application Workflow": [[7, "application-workflow"]], "Queries": [[7, "queries"]], "Logical Data Model": [[7, "logical-data-model"]], "Physical Data Model": [[7, "physical-data-model"]], "Deploy in ScyllaDB Cloud with Terraform": [[6, "deploy-in-scylladb-cloud-with-terraform"]], "Prerequisites": [[6, "prerequisites"]], "Get started": [[6, "get-started"]], "Clone the repository": [[6, "clone-the-repository"]], "Install CQLSH": [[6, "install-cqlsh"]], "Spin up a new ScyllaDB Cloud cluster": [[6, "spin-up-a-new-scylladb-cloud-cluster"]], "Build an IoT App with Python": [[4, "build-an-iot-app-with-python"]], "Clone repository and install dependencies": [[4, "clone-repository-and-install-dependencies"]], "Start Docker containers (skip this if you use Scylla Cloud)": [[4, "start-docker-containers-skip-this-if-you-use-scylla-cloud"]], "Connect to ScyllaDB and create the database schema": [[4, "connect-to-scylladb-and-create-the-database-schema"]], "Generate and ingest IoT data": [[4, "generate-and-ingest-iot-data"]], "Set up and test REST API": [[4, "set-up-and-test-rest-api"]], "Build an IoT App with Rust": [[5, "build-an-iot-app-with-rust"]], "Retrieving informations from API": [[5, "retrieving-informations-from-api"]], "Care Pet ScyllaDB PHP IoT example": [[3, "care-pet-scylladb-php-iot-example"]], "Quick Start": [[3, "quick-start"], [2, "quick-start"]], "Setup": [[3, "setup"]], "Useful Commands": [[3, "useful-commands"]], "PHP Application Commands": [[3, "php-application-commands"]], "Configuring the Environment": [[3, "configuring-the-environment"]], "Initializing Keyspace:": [[3, "initializing-keyspace"]], "Starting Web Server:": [[3, "starting-web-server"]], "Simulate Environment Sensors:": [[3, "simulate-environment-sensors"]], "Inserting Data": [[3, "inserting-data"]], "ScyllaDB Commands": [[3, "scylladb-commands"]], "Running Nodetool:": [[3, "running-nodetool"]], "Running Container Shell:": [[3, "running-container-shell"]], "Inspecting a Container": [[3, "inspecting-a-container"]], "Get Node IP Address:": [[3, "get-node-ip-address"]], "Build an IoT App with JavaScript": [[2, "build-an-iot-app-with-javascript"]], "Code Structure and Implementation": [[2, "code-structure-and-implementation"]], "Use ScyllaDB on your local machine": [[2, "use-scylladb-on-your-local-machine"]], "Run ScyllaDB on your local machine": [[2, "run-scylladb-on-your-local-machine"]], "Using Scylla Cloud": [[2, "using-scylla-cloud"], [2, "id1"], [2, "id3"]], "Output": [[2, "output"]], "migrate/index.js": [[2, "migrate-index-js"]], "Using ScyllaDB on your local machine": [[2, "using-scylladb-on-your-local-machine"], [2, "id2"]], "Using the Application": [[2, "using-the-application"]], "Getting Started with CarePet: A sample IoT App": [[8, "getting-started-with-carepet-a-sample-iot-app"]], "Requirements": [[8, "requirements"]], "Prerequisites for Deploying the Application": [[8, "prerequisites-for-deploying-the-application"]], "Use Case Requirements": [[8, "use-case-requirements"]], "Performance Requirements": [[8, "performance-requirements"]], "Deploying the Application in ScyllaDB Cloud": [[8, "deploying-the-application-in-scylladb-cloud"]], "Deploying the Application Locally": [[8, "deploying-the-application-locally"]], "Build the Application with Your Programming Language": [[8, "build-the-application-with-your-programming-language"]], "Additional Resources": [[8, "additional-resources"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/stable/sitemap.xml b/stable/sitemap.xml new file mode 100644 index 00000000..ff87b68f --- /dev/null +++ b/stable/sitemap.xml @@ -0,0 +1,2 @@ + +https://iot.scylladb.com/stable/build-with-go.htmlhttps://iot.scylladb.com/stable/build-with-java.htmlhttps://iot.scylladb.com/stable/build-with-javascript.htmlhttps://iot.scylladb.com/stable/build-with-python.htmlhttps://iot.scylladb.com/stable/build-with-php.htmlhttps://iot.scylladb.com/stable/design-and-data-model.htmlhttps://iot.scylladb.com/stable/build-with-rust.htmlhttps://iot.scylladb.com/stable/getting-started.htmlhttps://iot.scylladb.com/stable/deploy-in-cloud.htmlhttps://iot.scylladb.com/stable/index.htmlhttps://iot.scylladb.com/stable/genindex.htmlhttps://iot.scylladb.com/stable/404.htmlhttps://iot.scylladb.com/stable/search.html \ No newline at end of file