diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..e283e2eea9 --- /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 0000000000..63858016cb --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +rust-driver.docs.scylladb.com \ No newline at end of file diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 0000000000..30fee9d0f7 --- /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 0000000000..92fad4b5c0 --- /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 0000000000..54b3c46381 --- /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 0000000000..f1916ec7d1 --- /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 0000000000..2ea7ff3e21 --- /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 0000000000..dbe1aaad79 --- /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 0000000000..65eb0a5536 --- /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 0000000000..d06a71d751 --- /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 0000000000..7e4c114f21 --- /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 0000000000..a858a410e4 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 0000000000..f8520d5b3e --- /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 0000000000..f30770c7ed 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 0000000000..aae1708f26 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 0000000000..6c7484f082 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 0000000000..5448c7f007 --- /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 0000000000..09107d9520 --- /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 0000000000..1b1fcc83e3 --- /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 0000000000..7c2b4ebae0 --- /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 0000000000..7e93612026 --- /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 0000000000..67ebbc2f38 --- /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 0000000000..e1ce2c1d78 --- /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 0000000000..f4096cbf11 --- /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 0000000000..2a7c6ea0b7 --- /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 0000000000..3afa25c481 --- /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 0000000000..44eb829cdc --- /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 0000000000..875e421670 --- /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 0000000000..8c92469808 --- /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 0000000000..d1162b73e7 --- /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 0000000000..a9069bb6e5 --- /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 0000000000..cfb2318dae --- /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 0000000000..49d809a5df --- /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 0000000000..9df3145dd2 --- /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 0000000000..ee804197a0 --- /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 0000000000..5501492f3e --- /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 0000000000..97be900b50 --- /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 0000000000..ee1ac26283 --- /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 0000000000..ba5f211864 --- /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 0000000000..a7eb4b77a4 --- /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 0000000000..3806565367 --- /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 0000000000..37a709f7a8 --- /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 0000000000..702500be40 --- /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 0000000000..e8329c2afe --- /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 0000000000..f0b9c25419 --- /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 0000000000..906e87279c --- /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 0000000000..1ef0920d49 --- /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 0000000000..884451270d --- /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 0000000000..3094127dec --- /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 0000000000..dcb5916c26 --- /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 0000000000..0e6192a352 --- /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 0000000000..02b4e425be --- /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 0000000000..e34eb4504f --- /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 0000000000..97fa3a0e21 --- /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 0000000000..80b3787f66 --- /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 0000000000..40a3fd5f6f --- /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 0000000000..a952b59937 --- /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 0000000000..5b8d47eb15 --- /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 0000000000..60ebab3795 --- /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 0000000000..98c2ea7d5b --- /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 0000000000..bb7d8d3ea8 --- /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 0000000000..515c1528a2 --- /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 0000000000..d0146fc497 --- /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 0000000000..5757435085 --- /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 0000000000..74b01db168 --- /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 0000000000..80c490c7b0 --- /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 0000000000..6e3ab08e79 --- /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 0000000000..c8cbf67c8c --- /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 0000000000..81aae93eef --- /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 0000000000..fc164ea1e7 --- /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 0000000000..bebe9b8274 --- /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 0000000000..4b900bd0c0 --- /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 0000000000..a4228b34e8 --- /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 0000000000..df42b5522b --- /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 0000000000..2fe54efdbc --- /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 0000000000..3e7bcd6d90 --- /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 0000000000..226c44d853 --- /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 0000000000..bf7aa6af84 --- /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 0000000000..08b95a88ed --- /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 0000000000..e8ae088106 --- /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 0000000000..f7547ab959 --- /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 0000000000..47e56cddcf --- /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 0000000000..e4b1d40331 --- /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 0000000000..5e9f5cd427 --- /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 0000000000..3351e51d23 --- /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 0000000000..5206e58e98 --- /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 0000000000..4fff669cb6 --- /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 0000000000..b5022d7c4d --- /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 0000000000..769fa0889f 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 0000000000..7c06d01674 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 0000000000..d33fddd62f 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 0000000000..0462f893d5 --- /dev/null +++ b/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/_static/img/mascots/scylla-cloud.svg b/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 0000000000..a6c6a26fc9 --- /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 0000000000..d0368a7027 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 0000000000..0cdadaa216 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 0000000000..e889f4e368 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 0000000000..a5bce950c2 --- /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 0000000000..6012e71679 --- /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 0000000000..a1aa0b46ac --- /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 0000000000..f64c29e6c7 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 0000000000..d2f645c645 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 0000000000..0f53b26afa 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 0000000000..630f2d9094 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 0000000000..c87abe684d 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 0000000000..ba52cd223d 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 0000000000..cef08c8654 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 0000000000..75cccbfdf1 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 0000000000..6f10405f21 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 0000000000..e368cae169 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 0000000000..74ad669500 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 0000000000..6ba9ed937c --- /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 0000000000..48bec7dde3 --- /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 0000000000..956d1dd0e2 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 0000000000..7ee2b04338 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 0000000000..3b2dc8f1a2 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 0000000000..299e9cb995 --- /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 0000000000..655a450b2a --- /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 0000000000..b28dc857cc 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 0000000000..09342ac687 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 0000000000..9b4c613e70 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 0000000000..96dc785298 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 0000000000..f88598e05a 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 0000000000..6f0ca146c0 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 0000000000..b3d0621193 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 0000000000..b070bb022c 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 0000000000..6a8b16a6b4 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 0000000000..f3b8b2984f 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 0000000000..b38a6fbbe0 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 0000000000..954bf13bc2 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 0000000000..d35a13d380 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 0000000000..30ea1d901e --- /dev/null +++ b/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/_static/js/main.bundle.js b/_static/js/main.bundle.js new file mode 100644 index 0000000000..190a41642e --- /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 +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Authentication

      +

      Driver supports both authentication by username and password and custom authentication defined by a user.

      + +
      +

      Custom Authentication

      +

      A custom authentication is defined by implementing the AuthenticatorSession. +An AuthenticatorSession instance is created per session, so it is also necessary to define a AuthenticatorProvider for it. +Finally, to make use of the custom authentication, use the authenticator_provider method in SessionBuilder:

      +
      use bytes::{BufMut, BytesMut};
      +use async_trait::async_trait;
      +use scylla::authentication::{AuthError, AuthenticatorProvider, AuthenticatorSession};
      +
      +struct CustomAuthenticator;
      +
      +#[async_trait]
      +impl AuthenticatorSession for CustomAuthenticator {
      +    // to handle an authentication challenge initiated by the server.
      +    // The information contained in the token parameter is authentication protocol specific.
      +    // It may be NULL or empty. 
      +    async fn evaluate_challenge(
      +        &mut self,
      +        _token: Option<&[u8]>,
      +    ) -> Result<Option<Vec<u8>>, AuthError> {
      +        Err("Challenges are not expected".to_string())
      +    }
      +
      +    // to handle the success phase of exchange. The token parameters contain information that may be used to finalize the request.
      +    async fn success(&mut self, _token: Option<&[u8]>) -> Result<(), AuthError> {
      +        Ok(())
      +    }
      +}
      +
      +struct CustomAuthenticatorProvider;
      +
      +#[async_trait]
      +impl AuthenticatorProvider for CustomAuthenticatorProvider {
      +    async fn start_authentication_session(
      +        &self,
      +        _name: &str,
      +    ) -> Result<(Option<Vec<u8>>, Box<dyn AuthenticatorSession>), AuthError> {
      +        let mut response = BytesMut::new();
      +        let cred = "\0cassandra\0cassandra";
      +        let cred_length = 20;
      +
      +        response.put_i32(cred_length);
      +        response.put_slice(cred.as_bytes());
      +
      +        Ok((Some(response.to_vec()), Box::new(CustomAuthenticator)))
      +    }
      +}
      +
      +async fn authentication_example() -> Result<(), Box<dyn Error>> {
      +    use scylla::{Session, SessionBuilder};
      +
      +    let _session: Session = SessionBuilder::new()
      +        .known_node("127.0.0.1:9042")
      +        .authenticator_provider(Arc::new(CustomAuthenticatorProvider))
      +        .build()
      +        .await?;
      +
      +    Ok(())
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/connecting/compression.html b/main/connecting/compression.html new file mode 100644 index 0000000000..418b3a086c --- /dev/null +++ b/main/connecting/compression.html @@ -0,0 +1,648 @@ + + + + + + + + + + + + + Compression | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Compression

      +

      By default the driver does not use any compression on connections.
      +It’s possible to specify a preferred compression algorithm.
      +The driver will try using it, but if the database doesn’t support it, it will fall back to no compression.

      +

      Available compression algorithms:

      +
        +
      • Snappy

      • +
      • LZ4

      • +
      +

      An example enabling Snappy compression algorithm:

      +
      use scylla::{Session, SessionBuilder};
      +use scylla::transport::Compression;
      +use std::error::Error;
      +
      +#[tokio::main]
      +async fn main() -> Result<(), Box<dyn Error>> {
      +    let uri = std::env::var("SCYLLA_URI")
      +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
      +
      +    let session: Session = SessionBuilder::new()
      +        .known_node(uri)
      +        .compression(Some(Compression::Snappy))
      +        .build()
      +        .await?;
      +
      +    Ok(())
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/connecting/connecting.html b/main/connecting/connecting.html new file mode 100644 index 0000000000..9ee3aa1eb3 --- /dev/null +++ b/main/connecting/connecting.html @@ -0,0 +1,719 @@ + + + + + + + + + + + + + Connecting to the cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Connecting to the cluster

      +

      Scylla is a distributed database, which means that it operates on multiple nodes running independently. +When creating a Session you can specify a few known nodes to which the driver will try connecting:

      +
      use scylla::{Session, SessionBuilder};
      +use std::error::Error;
      +use std::time::Duration;
      +use std::net::{IpAddr, Ipv4Addr, SocketAddr};
      +
      +#[tokio::main]
      +async fn main() -> Result<(), Box<dyn Error>> {
      +    let uri = std::env::var("SCYLLA_URI")
      +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
      +
      +    let session: Session = SessionBuilder::new()
      +        .known_node(uri)
      +        .known_node("127.0.0.72:4321")
      +        .known_node("localhost:8000")
      +        .connection_timeout(Duration::from_secs(3))
      +        .cluster_metadata_refresh_interval(Duration::from_secs(10))
      +        .known_node_addr(SocketAddr::new(
      +            IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
      +            9000,
      +        ))
      +        .build()
      +        .await?;
      +
      +    Ok(())
      +}
      +
      +
      +

      After successfully connecting to some specified node the driver will fetch topology information about +other nodes in this cluster and connect to them as well.

      +
      +

      Best practices for using Session

      +
      +

      Warning

      +

      Always try to use only a single Session object per apllication because creating them is very expensive!

      +
      +

      The driver maintains its own pool of connections to each node and each connection is capable of handling multiple requests in parallel. Driver will also route requests to nodes / shards that actually own the data (unless the load balancing policy that you use doesn’t support it).

      +

      For those reasons, we recommend using one instance of Session per application.

      +

      Creating short-lived Session’s (e.g. Session per request) is strongly discouraged because it will result in great performance penalties because creating a Session is a costly process - it requires estabilishing a lot of TCP connections. +Creating many Session’s in one application (e.g. Session per thread / per Tokio task) is also discouraged, because it wastes resources - as mentioned before, Session maintains a connection pool itself and can handle parallel queries, so you would be holding a lot of connections unnecessarily.

      +

      If you need to share Session with different threads / Tokio tasks etc. use Arc<Session> - all methods of Session take &self, so it doesn’t hinder the functionality in any way.

      +
      +
      +

      Metadata

      +

      The driver refreshes the cluster metadata periodically, which contains information about cluster topology as well as the cluster schema. By default, the driver refreshes the cluster metadata every 60 seconds. +However, you can set the cluster_metadata_refresh_interval to a non-negative value to periodically refresh the cluster metadata. This is useful when you do not have unexpected amount of traffic or when you have an extra traffic causing topology to change frequently.

      +
      +
      +

      Scylla Cloud Serverless

      +

      Scylla Serverless is an elastic and dynamic deployment model. When creating a Session you need to +specify the secure connection bundle as follows:

      +
      use std::path::Path;
      +use std::error::Error;
      +use scylla::CloudSessionBuilder;
      +
      +#[tokio::main]
      +async fn main() -> Result<(), Box<dyn Error>> {
      +    let session = CloudSessionBuilder::new(Path::new("config_data.yaml"))
      +        .unwrap()
      +        .build()
      +        .await
      +        .unwrap();
      +
      +    Ok(())
      +}
      +
      +
      +

      Note that the bundle file will be provided after the serverless cluster is created. Here is an example of a +configuration file for a serverless cluster:

      +
      datacenters:
      +  datacenter1:
      +    certificateAuthorityData: CERTIFICATE_DATA
      +    server: 127.0.1.1:9142
      +    nodeDomain: cql.cluster-id.scylla.com
      +    insecureSkipTlsVerify: false
      +authInfos:
      +  default:
      +    clientCertificateData: CERTIFICATE_DATA
      +    clientKeyData: KEY_DATA
      +    username: scylladb
      +    password: scylladb
      +contexts:
      +  default:
      +    datacenterName: datacenter1
      +    authInfoName: default
      +currentContext: default
      +
      +
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/connecting/tls.html b/main/connecting/tls.html new file mode 100644 index 0000000000..c9c5bd6df9 --- /dev/null +++ b/main/connecting/tls.html @@ -0,0 +1,696 @@ + + + + + + + + + + + + + TLS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      TLS

      +

      Driver uses the openssl crate for TLS functionality.
      +It was chosen because rustls doesn’t support certificates for ip addresses +(see issue), which is a common use case for Scylla.

      +
      +

      Enabling feature

      +

      openssl is not a pure Rust library so you need enable a feature and install the proper package.

      +

      To enable the tls feature add in Cargo.toml:

      +
      scylla = { version = "0.4", features = ["ssl"] }
      +openssl = "0.10.32"
      +
      +
      +

      Then install the package with openssl:

      +
        +
      • Debian/Ubuntu:

        +
        apt install libssl-dev pkg-config
        +
        +
        +
      • +
      • Fedora:

        +
        dnf install openssl-devel
        +
        +
        +
      • +
      + +
        +
      • Arch:

        +
        pacman -S openssl pkg-config
        +
        +
        +
      • +
      +
      +
      +

      Using TLS

      +

      To use tls you will have to create an openssl +SslContext +and pass it to SessionBuilder

      +

      For example, if database certificate is in the file ca.crt:

      +
      use scylla::{Session, SessionBuilder};
      +use openssl::ssl::{SslContextBuilder, SslMethod, SslVerifyMode};
      +use std::path::PathBuf;
      +
      +let mut context_builder = SslContextBuilder::new(SslMethod::tls())?;
      +context_builder.set_ca_file("ca.crt")?;
      +context_builder.set_verify(SslVerifyMode::PEER);
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9142") // The the port is now 9142
      +    .ssl_context(Some(context_builder.build()))
      +    .build()
      +    .await?;
      +
      +
      +

      See the full example for more details

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/contents.html b/main/contents.html new file mode 100644 index 0000000000..f47781a900 --- /dev/null +++ b/main/contents.html @@ -0,0 +1,609 @@ + + + + + + + + + + + + + <no title> | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/blob.html b/main/data-types/blob.html new file mode 100644 index 0000000000..f414651cf7 --- /dev/null +++ b/main/data-types/blob.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Blob | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Blob

      +

      Blob is represented as Vec<u8>

      +
      use scylla::IntoTypedRows;
      +
      +// Insert some blob into the table as a Vec<u8>
      +// We can insert it by reference to not move the whole blob
      +let to_insert: Vec<u8> = vec![1, 2, 3, 4, 5];
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&to_insert,))
      +    .await?;
      +
      +// Read blobs from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(Vec<u8>,)>()?;
      +while let Some((blob_value,)) = iter.next().transpose()? {
      +    println!("{:?}", blob_value);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/collections.html b/main/data-types/collections.html new file mode 100644 index 0000000000..873a1068bf --- /dev/null +++ b/main/data-types/collections.html @@ -0,0 +1,749 @@ + + + + + + + + + + + + + List, Set, Map | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      List, Set, Map

      +
      +

      List

      +

      List is represented as Vec<T>

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a list of ints into the table
      +let my_list: Vec<i32> = vec![1, 2, 3, 4, 5];
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_list,))
      +    .await?;
      +
      +// Read a list of ints from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(Vec<i32>,)>()?;
      +while let Some((list_value,)) = iter.next().transpose()? {
      +    println!("{:?}", list_value);
      +}
      +
      +
      +
      +
      +

      Set

      +

      Set is represented as Vec<T>, HashSet<T> or BTreeSet<T>:

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a set of ints into the table
      +let my_set: Vec<i32> = vec![1, 2, 3, 4, 5];
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
      +    .await?;
      +
      +// Read a set of ints from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(Vec<i32>,)>()?;
      +while let Some((list_value,)) = iter.next().transpose()? {
      +    println!("{:?}", list_value);
      +}
      +
      +
      +
      use scylla::IntoTypedRows;
      +use std::collections::HashSet;
      +
      +// Insert a set of ints into the table
      +let my_set: HashSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
      +    .await?;
      +
      +// Read a set of ints from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(HashSet<i32>,)>()?;
      +while let Some((list_value,)) = iter.next().transpose()? {
      +    println!("{:?}", list_value);
      +}
      +
      +
      +
      use scylla::IntoTypedRows;
      +use std::collections::BTreeSet;
      +
      +// Insert a set of ints into the table
      +let my_set: BTreeSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
      +    .await?;
      +
      +// Read a set of ints from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(BTreeSet<i32>,)>()?;
      +while let Some((list_value,)) = iter.next().transpose()? {
      +    println!("{:?}", list_value);
      +}
      +
      +
      +
      +
      +

      Map

      +

      Map is represented as HashMap<K, V> or BTreeMap<K, V>

      +
      use scylla::IntoTypedRows;
      +use std::collections::HashMap;
      +
      +// Insert a map of text and int into the table
      +let mut my_map: HashMap<String, i32> = HashMap::new();
      +my_map.insert("abcd".to_string(), 16);
      +
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,))
      +    .await?;
      +
      +// Read a map from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(HashMap<String, i32>,)>()?;
      +while let Some((map_value,)) = iter.next().transpose()? {
      +    println!("{:?}", map_value);
      +}
      +
      +
      +
      use scylla::IntoTypedRows;
      +use std::collections::BTreeMap;
      +
      +// Insert a map of text and int into the table
      +let mut my_map: BTreeMap<String, i32> = BTreeMap::new();
      +my_map.insert("abcd".to_string(), 16);
      +
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,))
      +    .await?;
      +
      +// Read a map from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(BTreeMap<String, i32>,)>()?;
      +while let Some((map_value,)) = iter.next().transpose()? {
      +    println!("{:?}", map_value);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/counter.html b/main/data-types/counter.html new file mode 100644 index 0000000000..9b117983f4 --- /dev/null +++ b/main/data-types/counter.html @@ -0,0 +1,634 @@ + + + + + + + + + + + + + Counter | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Counter

      +

      Counter is represented as struct Counter(pub i64)
      +Counter can’t be inserted, it can only be read or updated.

      +
      use scylla::IntoTypedRows;
      +use scylla::frame::value::Counter;
      +
      +// Read counter from the table
      +let result = session.query("SELECT c FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(Counter,)>()?;
      +while let Some((counter_value,)) = iter.next().transpose()? {
      +    let counter_int_value: i64 = counter_value.0;
      +    println!("{}", counter_int_value);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/data-types.html b/main/data-types/data-types.html new file mode 100644 index 0000000000..2afd2874fe --- /dev/null +++ b/main/data-types/data-types.html @@ -0,0 +1,648 @@ + + + + + + + + + + + + + Data Types | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Data Types

      +

      The driver maps database data types to matching Rust types +to achieve seamless sending and receiving of CQL values.

      +

      See the following chapters for examples on how to send and receive each data type.

      +

      See Query values for more information about sending values in queries.
      +See Query result for more information about reading values from queries

      +

      Database types and their Rust equivalents:

      +
        +
      • Boolean <—-> bool

      • +
      • Tinyint <—-> i8

      • +
      • Smallint <—-> i16

      • +
      • Int <—-> i32

      • +
      • BigInt <—-> i64

      • +
      • Float <—-> f32

      • +
      • Double <—-> f64

      • +
      • Ascii, Text, Varchar <—-> &str, String

      • +
      • Counter <—-> value::Counter

      • +
      • Blob <—-> Vec<u8>

      • +
      • Inet <—-> std::net::IpAddr

      • +
      • Uuid <—-> uuid::Uuid

      • +
      • Timeuuid <—-> value::CqlTimeuuid

      • +
      • Date <—-> value::CqlDate, chrono::NaiveDate, time::Date

      • +
      • Time <—-> value::CqlTime, chrono::NaiveTime, time::Time

      • +
      • Timestamp <—-> value::CqlTimestamp, chrono::DateTime<Utc>, time::OffsetDateTime

      • +
      • Duration <—-> value::CqlDuration

      • +
      • Decimal <—-> value::CqlDecimal, bigdecimal::Decimal

      • +
      • Varint <—-> value::CqlVarint, num_bigint::BigInt (v0.3 and v0.4)

      • +
      • List <—-> Vec<T>

      • +
      • Set <—-> Vec<T>

      • +
      • Map <—-> std::collections::HashMap<K, V>

      • +
      • Tuple <—-> Rust tuples

      • +
      • UDT (User defined type) <—-> Custom user structs with macros

      • +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/date.html b/main/data-types/date.html new file mode 100644 index 0000000000..762d0008b5 --- /dev/null +++ b/main/data-types/date.html @@ -0,0 +1,717 @@ + + + + + + + + + + + + + Date | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Date

      +

      Depending on feature flags, three different types can be used to interact with date.

      +

      Internally date is represented as number of days since +-5877641-06-23 i.e. 2^31 days before unix epoch.

      +
      +

      CqlDate

      +

      Without any extra features enabled, only frame::value::CqlDate is available. It’s an +u32 wrapper and it matches the internal date representation.

      +

      However, for most use cases other types are more practical. See following sections for chrono and time.

      +
      use scylla::frame::value::CqlDate;
      +use scylla::IntoTypedRows;
      +
      +// 1970-01-08
      +let to_insert = CqlDate((1 << 31) + 7);
      +
      +// Insert date into the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read raw Date from the table
      +if let Some(rows) = session
      +    .query("SELECT a FROM keyspace.table", &[])
      +    .await?
      +    .rows
      +{
      +    for row in rows.into_typed::<(CqlDate,)>() {
      +        let (date_value,): (CqlDate,) = row?;
      +    }
      +}
      +
      +
      +
      +
      +

      chrono::NaiveDate

      +

      If full range is not required and chrono feature is enabled, +chrono::NaiveDate can be used. +chrono::NaiveDate supports dates from +-262145-01-01 to 262143-12-31.

      +
      use chrono::NaiveDate;
      +use scylla::IntoTypedRows;
      +
      +// 2021-03-24
      +let to_insert = NaiveDate::from_ymd_opt(2021, 3, 24).unwrap();
      +
      +// Insert date into the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read NaiveDate from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(NaiveDate,)>()?;
      +while let Some((date_value,)) = iter.next().transpose()? {
      +    println!("{:?}", date_value);
      +}
      +
      +
      +
      +
      +

      time::Date

      +

      Alternatively, time feature can be used to enable support of +time::Date. +time::Date’s value range depends on feature flags, see its +documentation to get more info.

      +
      use scylla::IntoTypedRows;
      +use time::{Date, Month};
      +
      +// 2021-03-24
      +let to_insert = Date::from_calendar_date(2021, Month::March, 24).unwrap();
      +
      +// Insert date into the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read Date from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(Date,)>()?;
      +while let Some((date_value,)) = iter.next().transpose()? {
      +    println!("{:?}", date_value);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/decimal.html b/main/data-types/decimal.html new file mode 100644 index 0000000000..bed57205b6 --- /dev/null +++ b/main/data-types/decimal.html @@ -0,0 +1,678 @@ + + + + + + + + + + + + + Decimal | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Decimal

      +

      Decimal is represented as value::CqlDecimal or bigdecimal::BigDecimal

      +
      +

      value::CqlDecimal

      +

      Without any feature flags, the user can interact with decimal type by making use of value::CqlDecimal which is a very simple wrapper representing the value as signed binary number in big-endian order with a 32-bit scale.

      +
      use scylla::IntoTypedRows;
      +use scylla::frame::value::CqlDecimal;
      +use std::str::FromStr;
      +
      +// Insert a decimal (123.456) into the table
      +let to_insert: CqlDecimal =
      +        CqlDecimal::from_signed_be_bytes_and_exponent(vec![0x01, 0xE2, 0x40], 3);
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a decimal from the table
      +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
      +    for row in rows.into_typed::<(CqlDecimal,)>() {
      +        let (decimal_value,): (CqlDecimal,) = row?;
      +    }
      +}
      +
      +
      +
      +
      +

      bigdecimal::BigDecimal

      +

      To make use of bigdecimal::Bigdecimal type, user should enable bigdecimal-04 crate feature.

      +
      use scylla::IntoTypedRows;
      +use bigdecimal::BigDecimal;
      +use std::str::FromStr;
      +
      +// Insert a decimal into the table
      +let to_insert: BigDecimal = BigDecimal::from_str("12345.0")?;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a decimal from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(BigDecimal,)>()?;
      +while let Some((decimal_value,)) = iter.next().transpose()? {
      +    println!("{:?}", decimal_value);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/duration.html b/main/data-types/duration.html new file mode 100644 index 0000000000..127d7962fa --- /dev/null +++ b/main/data-types/duration.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Duration | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Duration

      +

      Duration is represented as CqlDuration\

      +
      use scylla::IntoTypedRows;
      +use scylla::frame::value::CqlDuration;
      +
      +// Insert some duration into the table
      +let to_insert: CqlDuration = CqlDuration { months: 1, days: 2, nanoseconds: 3 };
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read duration from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(CqlDuration,)>()?;
      +while let Some((duration_value,)) = iter.next().transpose()? {
      +    println!("{:?}", duration_value);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/inet.html b/main/data-types/inet.html new file mode 100644 index 0000000000..5edf4b981d --- /dev/null +++ b/main/data-types/inet.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Inet | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Inet

      +

      Inet is represented as std::net::IpAddr

      +
      use scylla::IntoTypedRows;
      +use std::net::{IpAddr, Ipv4Addr};
      +
      +// Insert some ip address into the table
      +let to_insert: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read inet from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(IpAddr,)>()?;
      +while let Some((inet_value,)) = iter.next().transpose()? {
      +    println!("{:?}", inet_value);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/primitive.html b/main/data-types/primitive.html new file mode 100644 index 0000000000..90844be4d3 --- /dev/null +++ b/main/data-types/primitive.html @@ -0,0 +1,777 @@ + + + + + + + + + + + + + Bool, Tinyint, Smallint, Int, Bigint, Float, Double | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Bool, Tinyint, Smallint, Int, Bigint, Float, Double

      +
      +

      Bool

      +

      Bool is represented as rust bool

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a bool into the table
      +let to_insert: bool = true;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a bool from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(bool,)>()?;
      +while let Some((bool_value,)) = iter.next().transpose()? {
      +    println!("{}", bool_value);
      +}
      +
      +
      +
      +
      +

      Tinyint

      +

      Tinyint is represented as rust i8

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a tinyint into the table
      +let to_insert: i8 = 123;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a tinyint from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(i8,)>()?;
      +while let Some((tinyint_value,)) = iter.next().transpose()? {
      +    println!("{:?}", tinyint_value);
      +}
      +
      +
      +
      +
      +

      Smallint

      +

      Smallint is represented as rust i16

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a smallint into the table
      +let to_insert: i16 = 12345;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a smallint from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(i16,)>()?;
      +while let Some((smallint_value,)) = iter.next().transpose()? {
      +    println!("{}", smallint_value);
      +}
      +
      +
      +
      +
      +

      Int

      +

      Int is represented as rust i32

      +
      use scylla::IntoTypedRows;
      +
      +// Insert an int into the table
      +let to_insert: i32 = 12345;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read an int from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(i32,)>()?;
      +while let Some((int_value,)) = iter.next().transpose()? {
      +    println!("{}", int_value);
      +}
      +
      +
      +
      +
      +

      Bigint

      +

      Bigint is represented as rust i64

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a bigint into the table
      +let to_insert: i64 = 12345;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a bigint from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(i64,)>()?;
      +while let Some((bigint_value,)) = iter.next().transpose()? {
      +    println!("{:?}", bigint_value);
      +}
      +
      +
      +
      +
      +

      Float

      +

      Float is represented as rust f32

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a float into the table
      +let to_insert: f32 = 123.0;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a float from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(f32,)>()?;
      +while let Some((float_value,)) = iter.next().transpose()? {
      +    println!("{:?}", float_value);
      +}
      +
      +
      +
      +
      +

      Double

      +

      Double is represented as rust f64

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a double into the table
      +let to_insert: f64 = 12345.0;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a double from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(f64,)>()?;
      +while let Some((double_value,)) = iter.next().transpose()? {
      +    println!("{:?}", double_value);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/text.html b/main/data-types/text.html new file mode 100644 index 0000000000..a84d8afcb1 --- /dev/null +++ b/main/data-types/text.html @@ -0,0 +1,643 @@ + + + + + + + + + + + + + Ascii, Text, Varchar | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Ascii, Text, Varchar

      +

      Ascii, Text and Varchar are represented as &str and String

      +
      use scylla::IntoTypedRows;
      +
      +// Insert some text into the table as a &str
      +let to_insert_str: &str = "abcdef";
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_str,))
      +    .await?;
      +
      +// Insert some text into the table as a String
      +let to_insert_string: String = "abcdef".to_string();
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_string,))
      +    .await?;
      +
      +// Read ascii/text/varchar from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(String,)>()?;
      +while let Some((text_value,)) = iter.next().transpose()? {
      +    println!("{}", text_value);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/time.html b/main/data-types/time.html new file mode 100644 index 0000000000..14dc67f6cd --- /dev/null +++ b/main/data-types/time.html @@ -0,0 +1,715 @@ + + + + + + + + + + + + + Time | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Time

      +

      Depending on feature flags used, three different types can be used to interact with time.

      +

      Internally time is represented as number of nanoseconds since +midnight. It can’t be negative or exceed 86399999999999 (23:59:59.999999999).

      +
      +

      CqlTime

      +

      Without any extra features enabled, only frame::value::CqlTime is available. It’s an +i64 wrapper and it matches the internal time representation.

      +

      However, for most use cases other types are more practical. See following sections for chrono and time.

      +
      use scylla::frame::value::CqlTime;
      +use scylla::IntoTypedRows;
      +
      +// 64 seconds since midnight
      +let to_insert = CqlTime(64 * 1_000_000_000);
      +
      +// Insert time into the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read time from the table
      +if let Some(rows) = session
      +    .query("SELECT a FROM keyspace.table", &[])
      +    .await?
      +    .rows
      +{
      +    for row in rows.into_typed::<(CqlTime,)>() {
      +        let (time_value,): (CqlTime,) = row?;
      +    }
      +}
      +
      +
      +
      +
      +

      chrono::NaiveTime

      +

      If chrono feature is enabled, chrono::NaiveTime +can be used to interact with the database. Although chrono can represent leap seconds, they are not supported. +Attempts to convert chrono::NaiveTime with leap +second to CqlTime or write it to the database will return an error.

      +
      use chrono::NaiveTime;
      +use scylla::IntoTypedRows;
      +
      +// 01:02:03.456,789,012
      +let to_insert = NaiveTime::from_hms_nano_opt(1, 2, 3, 456_789_012);
      +
      +// Insert time into the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read time from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(NaiveTime,)>()?;
      +while let Some((time_value,)) = iter.next().transpose()? {
      +    println!("{:?}", time_value);
      +}
      +
      +
      +
      +
      +

      time::Time

      +

      If time feature is enabled, time::Time can be used to interact +with the database.

      +
      use scylla::IntoTypedRows;
      +use time::Time;
      +
      +// 01:02:03.456,789,012
      +let to_insert = Time::from_hms_nano(1, 2, 3, 456_789_012).unwrap();
      +
      +// Insert time into the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read time from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(Time,)>()?;
      +while let Some((time_value,)) = iter.next().transpose()? {
      +    println!("{:?}", time_value);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/timestamp.html b/main/data-types/timestamp.html new file mode 100644 index 0000000000..b6e20736f0 --- /dev/null +++ b/main/data-types/timestamp.html @@ -0,0 +1,727 @@ + + + + + + + + + + + + + Timestamp | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Timestamp

      +

      Depending on feature flags, three different types can be used to interact with timestamps.

      +

      Internally timestamp is represented as +i64 describing number of milliseconds since unix epoch.

      +
      +

      CqlTimestamp

      +

      Without any extra features enabled, only frame::value::CqlTimestamp is available. It’s an +i64 wrapper and it matches the internal time representation. It’s +the only type that supports full range of values that database accepts.

      +

      However, for most use cases other types are more practical. See following sections for chrono and time.

      +
      use scylla::frame::value::CqlTimestamp;
      +use scylla::IntoTypedRows;
      +
      +// 64 seconds since unix epoch, 1970-01-01 00:01:04
      +let to_insert = CqlTimestamp(64 * 1000);
      +
      +// Write timestamp to the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read timestamp from the table
      +if let Some(rows) = session
      +    .query("SELECT a FROM keyspace.table", &[])
      +    .await?
      +    .rows
      +{
      +    for row in rows.into_typed::<(CqlTimestamp,)>() {
      +        let (timestamp_value,): (CqlTimestamp,) = row?;
      +    }
      +}
      +
      +
      +
      +
      +

      chrono::DateTime

      +

      If full value range is not required, chrono feature can be used to enable support of +chrono::DateTime. All values are expected to be converted +to UTC timezone explicitly, as timestamp doesn’t store +timezone information. Any precision finer than 1ms will be lost.

      +
      use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
      +use scylla::IntoTypedRows;
      +
      +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123
      +let to_insert = NaiveDateTime::new(
      +    NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(),
      +    NaiveTime::from_hms_milli_opt(0, 1, 4, 123).unwrap(),
      +)
      +.and_utc();
      +
      +// Write timestamp to the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read timestamp from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(DateTime<Utc>,)>()?;
      +while let Some((timestamp_value,)) = iter.next().transpose()? {
      +    println!("{:?}", timestamp_value);
      +}
      +
      +
      +
      +
      +

      time::OffsetDateTime

      +

      Alternatively, time feature can be used to enable support of +time::OffsetDateTime. As +timestamp doesn’t support timezone information, time will +be corrected to UTC and timezone info will be erased on write. On read, UTC timestamp is returned. Any precision finer +than 1ms will also be lost.

      +
      use scylla::IntoTypedRows;
      +use time::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time};
      +
      +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123
      +let to_insert = PrimitiveDateTime::new(
      +    Date::from_calendar_date(1970, Month::January, 1).unwrap(),
      +    Time::from_hms_milli(0, 1, 4, 123).unwrap(),
      +)
      +.assume_utc();
      +
      +// Write timestamp to the table
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read timestamp from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(OffsetDateTime,)>()?;
      +while let Some((timestamp_value,)) = iter.next().transpose()? {
      +    println!("{:?}", timestamp_value);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/timeuuid.html b/main/data-types/timeuuid.html new file mode 100644 index 0000000000..5408060392 --- /dev/null +++ b/main/data-types/timeuuid.html @@ -0,0 +1,686 @@ + + + + + + + + + + + + + Timeuuid | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Timeuuid

      +

      The Timeuuid type is represented as value::CqlTimeuuid.

      +

      Also, value::CqlTimeuuid is a wrapper for uuid::Uuid with custom ordering logic which follows Scylla/Cassandra semantics.

      +
      use scylla::IntoTypedRows;
      +use scylla::frame::value::CqlTimeuuid;
      +
      +// Insert some timeuuid into the table
      +let to_insert: CqlTimeuuid = CqlTimeuuid::from_str("8e14e760-7fa8-11eb-bc66-000000000001")?;
      +
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read Timeuuid from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +
      +let mut iter = result.rows_typed::<(CqlTimeuuid, )>()?;
      +
      +while let Some((timeuuid,)) = iter.next().transpose()? {
      +    println!("Read a value from row: {}", timeuuid);
      +}
      +
      +
      +
      +

      Creating your own Timeuuid

      +

      To create your own Timeuuid objects from timestamp-based uuid v1, you need to enable the feature v1 of uuid crate using:

      +
      cargo add uuid -F v1
      +
      +
      +

      and now you’re gonna be able to use the uuid::v1 features:

      +
      use scylla::IntoTypedRows;
      +use scylla::frame::value::CqlTimeuuid;
      +use uuid::Uuid;
      +
      +// Tip: you can use random stable numbers or your MAC Address
      +let node_id = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC];
      +
      +// Build your Timeuuid with the current timestamp
      +let to_insert = CqlTimeuuid::from(Uuid::now_v1(&node_id));
      +
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))  
      +    .await?;
      +
      +// Read Timeuuid from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +
      +let mut iter = result.rows_typed::<(CqlTimeuuid, )>()?;
      +
      +while let Some((timeuuid,)) = iter.next().transpose()? {
      +    println!("Read a value from row: {}", timeuuid);
      +}
      +
      +
      +

      Learn more about UUID::v1 here.

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/tuple.html b/main/data-types/tuple.html new file mode 100644 index 0000000000..b2eb31b43a --- /dev/null +++ b/main/data-types/tuple.html @@ -0,0 +1,639 @@ + + + + + + + + + + + + + Tuple | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Tuple

      +

      Tuple is represented as rust tuples of max 16 elements.

      +
      use scylla::IntoTypedRows;
      +
      +// Insert a tuple of int and string into the table
      +let to_insert: (i32, String) = (1, "abc".to_string());
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a tuple of int and string from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<((i32, String),)>()?;
      +while let Some((tuple_value,)) = iter.next().transpose()? {
      +    let int_value: i32 = tuple_value.0;
      +    let string_value: String = tuple_value.1;
      +    println!("({}, {})", int_value, string_value);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/udt.html b/main/data-types/udt.html new file mode 100644 index 0000000000..9ac953c1a4 --- /dev/null +++ b/main/data-types/udt.html @@ -0,0 +1,689 @@ + + + + + + + + + + + + + User defined types | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      User defined types

      +

      Scylla allows users to define their own data types with named fields (See the official documentation)
      +To use user defined types in the driver, you can create a corresponding struct in Rust, and use it to read and write UDT values.

      +

      For example let’s say my_type was created using this query:

      +
      CREATE TYPE ks.my_type (int_val int, text_val text)
      +
      +
      +

      To use this type in the driver, create a matching struct and derive:

      +
        +
      • SerializeCql: in order to be able to use this struct in query parameters.
        +This macro requires fields of UDT and struct to have matching names, but the order +of the fields is not required to be the same.
        +Note: you can use different name using rename attribute - see SerializeCql macro documentation.

      • +
      • FromUserType: in order to be able to use this struct in query results.
        +This macro requires fields of UDT and struct to be in the same ORDER.
        +This mismatch between SerializeCql and FromUserType requirements is a temporary situation - in the future FromUserType (or the macro that replaces it) will also require matching names.

      • +
      +
      use scylla::macros::{FromUserType, SerializeCql};
      +
      +// Define a custom struct that matches the User Defined Type created earlier.
      +// Fields must be in the same order as they are in the database and also
      +// have the same names.
      +// Wrapping a field in Option will gracefully handle null field values.
      +#[derive(Debug, FromUserType, SerializeCql)]
      +struct MyType {
      +    int_val: i32,
      +    text_val: Option<String>,
      +}
      +
      +
      +
      +

      Important
      +For deserialization, fields in the Rust struct must be defined in the same order as they are in the database. +When receiving values, the driver will (de)serialize fields one after another, without looking at field names.

      +
      +
      +

      Important
      +For serialization, by default fields in the Rust struct must be defined with the same names as they are in the database. +The driver will serialize the fields in the order defined by the UDT, matching Rust fields by name. +You can change this behaviour using macro attributes, see SerializeCql macro documentation for more information.

      +
      +

      Now it can be sent and received just like any other CQL value:

      +
      use scylla::IntoTypedRows;
      +use scylla::macros::{FromUserType, SerializeCql};
      +use scylla::cql_to_rust::FromCqlVal;
      +
      +#[derive(Debug, FromUserType, SerializeCql)]
      +struct MyType {
      +    int_val: i32,
      +    text_val: Option<String>,
      +}
      +
      +// Insert my_type into the table
      +let to_insert = MyType {
      +    int_val: 17,
      +    text_val: Some("Some string".to_string()),
      +};
      +
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read MyType from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(MyType,)>()?;
      +while let Some((my_type_value,)) = iter.next().transpose()? {
      +    println!("{:?}", my_type_value);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/uuid.html b/main/data-types/uuid.html new file mode 100644 index 0000000000..cc97a8407c --- /dev/null +++ b/main/data-types/uuid.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Uuid | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Uuid

      +

      Uuid is represented as uuid::Uuid.

      +
      use scylla::IntoTypedRows;
      +use uuid::Uuid;
      +
      +// Insert some uuid into the table
      +let to_insert: Uuid = Uuid::parse_str("8e14e760-7fa8-11eb-bc66-000000000001")?;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read uuid from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(Uuid,)>()?;
      +while let Some((uuid_value,)) = iter.next().transpose()? {
      +    println!("{:?}", uuid_value);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/data-types/varint.html b/main/data-types/varint.html new file mode 100644 index 0000000000..6e8657404e --- /dev/null +++ b/main/data-types/varint.html @@ -0,0 +1,664 @@ + + + + + + + + + + + + + Varint | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Varint

      +

      Varint is represented as value::CqlVarint or num_bigint::BigInt.

      +
      +

      num_bigint::BigInt

      +

      To make use of num_bigint::BigInt type, user should enable one of the available feature flags (num-bigint-03 or num-bigint-04). They enable support for num_bigint::BigInt v0.3 and v0.4 accordingly.

      +
      +
      +

      value::CqlVarint

      +

      Without any feature flags, the user can interact with Varint type by making use of value::CqlVarint which +is a very simple wrapper representing the value as signed binary number in big-endian order.

      +
      +
      +

      Example

      +
      use scylla::IntoTypedRows;
      +use num_bigint::BigInt;
      +use std::str::FromStr;
      +
      +// Insert a varint into the table
      +let to_insert: BigInt = BigInt::from_str("12345")?;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +// Read a varint from the table
      +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
      +let mut iter = result.rows_typed::<(BigInt,)>()?;
      +while let Some((varint_value,)) = iter.next().transpose()? {
      +    println!("{:?}", varint_value);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/execution-profiles/create-and-use.html b/main/execution-profiles/create-and-use.html new file mode 100644 index 0000000000..60c0d9d3ab --- /dev/null +++ b/main/execution-profiles/create-and-use.html @@ -0,0 +1,695 @@ + + + + + + + + + + + + + Creating a profile and setting it | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Creating a profile and setting it

      +
      +

      Example

      +

      To create an ExecutionProfile and attach it as default for Session:

      +
      use scylla::{Session, SessionBuilder};
      +use scylla::statement::Consistency;
      +use scylla::transport::ExecutionProfile;
      +
      +let profile = ExecutionProfile::builder()
      +    .consistency(Consistency::LocalOne)
      +    .request_timeout(None) // no request timeout
      +    .build();
      +
      +let handle = profile.into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .default_execution_profile_handle(handle)
      +    .build()
      +    .await?;
      +
      +
      +
      +
      +

      Example

      +

      To create an ExecutionProfile and attach it to a Query:

      +
      use scylla::query::Query;
      +use scylla::statement::Consistency;
      +use scylla::transport::ExecutionProfile;
      +use std::time::Duration;
      +
      +let profile = ExecutionProfile::builder()
      +    .consistency(Consistency::All)
      +    .request_timeout(Some(Duration::from_secs(30)))
      +    .build();
      +
      +let handle = profile.into_handle();
      +
      +let mut query1 = Query::from("SELECT * FROM ks.table");
      +query1.set_execution_profile_handle(Some(handle.clone()));
      +
      +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?");
      +query2.set_execution_profile_handle(Some(handle));
      +
      +
      +
      +
      +

      Example

      +

      To create an ExecutionProfile based on another profile:

      +
      use scylla::statement::Consistency;
      +use scylla::transport::ExecutionProfile;
      +use std::time::Duration;
      +
      +let base_profile = ExecutionProfile::builder()
      +    .request_timeout(Some(Duration::from_secs(30)))
      +    .build();
      +
      +let profile = base_profile.to_builder()
      +    .consistency(Consistency::All)
      +    .build();
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/execution-profiles/execution-profiles.html b/main/execution-profiles/execution-profiles.html new file mode 100644 index 0000000000..492a21ead9 --- /dev/null +++ b/main/execution-profiles/execution-profiles.html @@ -0,0 +1,629 @@ + + + + + + + + + + + + + Execution profiles | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Execution profiles

      +

      Execution profiles are a way to group various query execution configuration options together. Profiles can be created to represent different workloads, which can be run conveniently on a single session.

      +

      The settings that an execution profile encapsulates are as follows:

      +
        +
      • consistency

      • +
      • serial consistency

      • +
      • request timeout

      • +
      • load balancing policy

      • +
      • retry policy

      • +
      • speculative execution policy

      • +
      +

      There are two classes of objects related to execution profiles: ExecutionProfile and ExecutionProfileHandle. The former is simply an immutable set of the settings. The latter is a handle that at particular moment points to some ExecutionProfile (but during its lifetime, it can change the profile it points at). Handles are assigned to Sessions and Statements.
      +
      +At any moment, handles can be remapped to point to another ExecutionProfile. This allows convenient switching between workloads for all Sessions and/or Statements that, for instance, share common characteristics.

      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/execution-profiles/maximal-example.html b/main/execution-profiles/maximal-example.html new file mode 100644 index 0000000000..6796f4a263 --- /dev/null +++ b/main/execution-profiles/maximal-example.html @@ -0,0 +1,665 @@ + + + + + + + + + + + + + All options supported by a profile | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      All options supported by a profile

      +
      +

      Example

      +

      ExecutionProfile supports all the following options:

      +
      use scylla::query::Query;
      +use scylla::speculative_execution::SimpleSpeculativeExecutionPolicy;
      +use scylla::statement::{Consistency, SerialConsistency};
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::load_balancing::DefaultPolicy;
      +use scylla::transport::retry_policy::FallthroughRetryPolicy;
      +use std::{sync::Arc, time::Duration};
      +
      +let profile = ExecutionProfile::builder()
      +    .consistency(Consistency::All)
      +    .serial_consistency(Some(SerialConsistency::Serial))
      +    .request_timeout(Some(Duration::from_secs(30)))
      +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
      +    .load_balancing_policy(Arc::new(DefaultPolicy::default()))
      +    .speculative_execution_policy(
      +        Some(
      +            Arc::new(
      +                SimpleSpeculativeExecutionPolicy {
      +                    max_retry_count: 3,
      +                    retry_interval: Duration::from_millis(100),
      +                }
      +            )
      +        )
      +    )
      +    .build();
      +
      +let mut query = Query::from("SELECT * FROM ks.table");
      +query.set_execution_profile_handle(Some(profile.into_handle()));
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/execution-profiles/priority.html b/main/execution-profiles/priority.html new file mode 100644 index 0000000000..dfe36b3421 --- /dev/null +++ b/main/execution-profiles/priority.html @@ -0,0 +1,677 @@ + + + + + + + + + + + + + Priorities of execution settings | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Priorities of execution settings

      +

      You always have a default execution profile set for the Session, either the default one or overridden upon Session creation. Moreover, you can set a profile for specific statements, in which case the statement’s profile has higher priority. Some options are also available for specific statements to be set directly on them, such as request timeout and consistency. In such case, the directly set options are preferred over those specified in execution profiles.

      +
      +

      Recap
      +Priorities are as follows:
      +Session’s default profile < Statement’s profile < options set directly on a Statement

      +
      +
      +

      Example

      +

      Priorities of execution profiles and directly set options:

      +
      use scylla::{Session, SessionBuilder};
      +use scylla::query::Query;
      +use scylla::statement::Consistency;
      +use scylla::transport::ExecutionProfile;
      +
      +let session_profile = ExecutionProfile::builder()
      +    .consistency(Consistency::One)
      +    .build();
      +
      +let query_profile = ExecutionProfile::builder()
      +    .consistency(Consistency::Two)
      +    .build();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .default_execution_profile_handle(session_profile.into_handle())
      +    .build()
      +    .await?;
      +
      +let mut query = Query::from("SELECT * FROM ks.table");
      +
      +// Query is not assigned any specific profile, so session's profile is applied.
      +// Therefore, the query will be executed with Consistency::One.
      +session.query(query.clone(), ()).await?;
      +
      +query.set_execution_profile_handle(Some(query_profile.into_handle()));
      +// Query's profile is applied.
      +// Therefore, the query will be executed with Consistency::Two.
      +session.query(query.clone(), ()).await?;
      +
      +query.set_consistency(Consistency::Three);
      +// An option is set directly on the query.
      +// Therefore, the query will be executed with Consistency::Three.
      +session.query(query, ()).await?;
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/execution-profiles/remap.html b/main/execution-profiles/remap.html new file mode 100644 index 0000000000..5819e559f2 --- /dev/null +++ b/main/execution-profiles/remap.html @@ -0,0 +1,700 @@ + + + + + + + + + + + + + Remapping execution profile handles | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Remapping execution profile handles

      +

      ExecutionProfileHandles can be remapped to another ExecutionProfile, and the change affects all sessions and statements that have been assigned that handle. This enables quick workload switches.

      +

      Example mapping:

      +
        +
      • session1 -> handle1 -> profile1

      • +
      • statement1 -> handle1 -> profile1

      • +
      • statement2 -> handle2 -> profile2

      • +
      +

      We can now remap handle2 to profile1, so that the mapping for statement2 becomes as follows:

      +
        +
      • statement2 -> handle2 -> profile1

      • +
      +

      We can also change statement1’s handle to handle2, and remap handle1 to profile2, yielding:

      +
        +
      • session1 -> handle1 -> profile2

      • +
      • statement1 -> handle2 -> profile1

      • +
      • statement2 -> handle2 -> profile1

      • +
      +

      As you can see, profiles are a powerful and convenient way to define and modify your workloads.

      +
      +

      Example

      +

      Below, the remaps described above are followed in code.

      +
      use scylla::{Session, SessionBuilder};
      +use scylla::query::Query;
      +use scylla::statement::Consistency;
      +use scylla::transport::ExecutionProfile;
      +
      +let profile1 = ExecutionProfile::builder()
      +    .consistency(Consistency::One)
      +    .build();
      +
      +let profile2 = ExecutionProfile::builder()
      +    .consistency(Consistency::Two)
      +    .build();
      +
      +let mut handle1 = profile1.clone().into_handle();
      +let mut handle2 = profile2.clone().into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .default_execution_profile_handle(handle1.clone())
      +    .build()
      +    .await?;
      +
      +let mut query1 = Query::from("SELECT * FROM ks.table");
      +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?");
      +
      +query1.set_execution_profile_handle(Some(handle1.clone()));
      +query2.set_execution_profile_handle(Some(handle2.clone()));
      +
      +// session1 -> handle1 -> profile1
      +// query1 -> handle1 -> profile1
      +// query2 -> handle2 -> profile2
      +
      +// We can now remap handle2 to profile1:
      +handle2.map_to_another_profile(profile1);
      +// ...so that the mapping for query2 becomes as follows:
      +// query2 -> handle2 -> profile1
      +
      +// We can also change query1's handle to handle2:
      +query1.set_execution_profile_handle(Some(handle2.clone()));
      +// ...and remap handle1 to profile2:
      +handle1.map_to_another_profile(profile2);
      +// ...yielding:
      +// session1 -> handle1 -> profile2
      +// query1 -> handle2 -> profile1
      +// query2 -> handle2 -> profile1
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/genindex.html b/main/genindex.html new file mode 100644 index 0000000000..28156e6e20 --- /dev/null +++ b/main/genindex.html @@ -0,0 +1,595 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + + + +
      + + + + + +
      + + +
      + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/index.html b/main/index.html new file mode 100644 index 0000000000..f1a06c99dc --- /dev/null +++ b/main/index.html @@ -0,0 +1,646 @@ + + + + + + + + + + + + + Scylla Rust Driver | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Scylla Rust Driver

      +

      This book contains documentation for scylla-rust-driver - a driver +for the Scylla database written in Rust. +Although optimized for Scylla, the driver is also compatible with Apache Cassandra®.

      +
      +

      Other documentation

      + +
      +
      +

      Contents

      + +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/load-balancing/default-policy.html b/main/load-balancing/default-policy.html new file mode 100644 index 0000000000..e6659e7350 --- /dev/null +++ b/main/load-balancing/default-policy.html @@ -0,0 +1,802 @@ + + + + + + + + + + + + + DefaultPolicy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      DefaultPolicy

      +

      DefaultPolicy is the default load balancing policy in Scylla Rust Driver. It +can be configured to be datacenter-aware and token-aware. Datacenter failover +for queries with non-local consistency mode is also supported.

      +
      +

      Creating a DefaultPolicy

      +

      DefaultPolicy can be created only using DefaultPolicyBuilder. The +builder() method of DefaultPolicy returns a new instance of +DefaultPolicyBuilder with the following default values:

      +
        +
      • preferences: no particular datacenter/rack preference

      • +
      • is_token_aware: true

      • +
      • permit_dc_failover: false

      • +
      • latency_awareness: None

      • +
      +

      You can use the builder methods to configure the desired settings and create a +DefaultPolicy instance:

      +
      use scylla::load_balancing::DefaultPolicy;
      +
      +let default_policy = DefaultPolicy::builder()
      +        .prefer_datacenter_and_rack("dc1".to_string(), "rack1".to_string())
      +        .token_aware(true)
      +        .permit_dc_failover(true)
      +        .build();
      +
      +
      +
      +

      Semantics of DefaultPolicy

      +
      +

      Preferences

      +

      The preferences field in DefaultPolicy allows the load balancing +policy to prioritize nodes based on their location. It has three modes:

      +
        +
      • no preference

      • +
      • preferred datacenter

      • +
      • preferred datacenter and rack

      • +
      +

      When a datacenter "my_dc" is preferred, the policy will treat nodes in "my_dc" +as “local” nodes, and nodes in other datacenters as “remote” nodes. This affects +the order in which nodes are returned by the policy when selecting nodes for +read or write operations. If no datacenter is preferred, the policy will treat +all nodes as local nodes.

      +

      preferences allow the load balancing policy to prioritize nodes based on their +availability zones (racks) in the preferred datacenter, too. When a datacenter +and a rack are preferred, the policy will first return replicas in the local rack +in the preferred datacenter, and then the other replicas in the datacenter +(followed by remote replicas). After replicas, the other node will be ordered +similarly, too (local rack nodes, local datacenter nodes, remote nodes).

      +

      When datacenter failover is disabled (permit_dc_failover is set to +false), the default policy will only include local nodes in load balancing +plans. Remote nodes will be excluded, even if they are alive and available to +serve requests.

      +
      +
      +

      Datacenter Failover

      +

      In the event of a datacenter outage or network failure, the nodes in that +datacenter may become unavailable, and clients may no longer be able to access +the data stored on those nodes. To address this, the DefaultPolicy supports +datacenter failover, which allows to route requests to nodes in other datacenters +if the local nodes are unavailable.

      +

      Datacenter failover can be enabled in DefaultPolicy by permit_dc_failover +setting in the builder. When this flag is set, the policy will prefer to return +alive remote replicas if datacenter failover is permitted and possible due to +consistency constraints.

      +
      +
      +

      Token awareness

      +

      Token awareness refers to a mechanism by which the driver is aware of the token +range assigned to each node in the cluster. Tokens are assigned to nodes to +partition the data and distribute it across the cluster.

      +

      When a user wants to read or write data, the driver can use token awareness to +route the request to the correct node based on the token range of the data +being accessed. This can help to minimize network traffic and improve +performance by ensuring that the data is accessed locally as much as possible.

      +

      In the case of DefaultPolicy, token awareness is enabled by default, meaning +that the policy will prefer to return alive local replicas if the token is +available. This means that if the client is requesting data that falls within +the token range of a particular node, the policy will try to route the request +to that node first, assuming it is alive and responsive.

      +

      Token awareness can significantly improve the performance and scalability of +applications built on Scylla. By using token awareness, users can ensure that +data is accessed locally as much as possible, reducing network overhead and +improving throughput.

      +

      Please note that for token awareness to be applied, a statement must be +prepared before being executed.

      +
      +
      +
      +

      Latency awareness

      +

      Latency awareness is a mechanism that penalises nodes whose measured recent +average latency classifies it as falling behind the others.

      +

      Every update_rate the global minimum average latency is computed, +and all nodes whose average latency is worse than exclusion_threshold +times the global minimum average latency become penalised for +retry_period. Penalisation involves putting those nodes at the very end +of the query plan. As it is often not truly beneficial to prefer +faster non-replica than replicas lagging behind the non-replicas, +this mechanism may as well worsen latencies and/or throughput.

      +
      +

      Warning

      +

      Using latency awareness is NOT recommended, unless prior +benchmarks prove its beneficial impact on the specific workload’s +performance. Use with caution.

      +
      +
      +
      +

      Creating a latency aware DefaultPolicy

      +
      use scylla::load_balancing::{
      +    LatencyAwarenessBuilder, DefaultPolicy
      +};
      +use std::time::Duration;
      +
      +let latency_awareness_builder = LatencyAwarenessBuilder::new()
      +    .exclusion_threshold(3.)
      +    .update_rate(Duration::from_secs(3))
      +    .retry_period(Duration::from_secs(30))
      +    .minimum_measurements(200);
      +
      +let policy = DefaultPolicy::builder()
      +        // Here further customisation is, of course, possible.
      +        // e.g.: .prefer_datacenter(...)
      +        .latency_awareness(latency_awareness_builder)
      +        .build();
      +
      +
      +
      use scylla::load_balancing::DefaultPolicy;
      +
      +let default_policy = DefaultPolicy::builder()
      +        .prefer_datacenter("dc1".to_string())
      +        .token_aware(true)
      +        .permit_dc_failover(true)
      +        .build();
      +
      +
      +
      +
      +

      Node order in produced plans

      +

      The DefaultPolicy prefers to return nodes in the following order:

      +
        +
      1. Alive local replicas (if token is available & token awareness is enabled)

      2. +
      3. Alive remote replicas (if datacenter failover is permitted & possible due to consistency constraints)

      4. +
      5. Alive local nodes

      6. +
      7. Alive remote nodes (if datacenter failover is permitted & possible due to consistency constraints)

      8. +
      9. Enabled down nodes +And only if latency awareness is enabled:

      10. +
      11. Penalised: alive local replicas, alive remote replicas, … (in order as above).

      12. +
      +

      If no preferred datacenter is specified, all nodes are treated as local ones.

      +

      Replicas in the same priority groups are shuffled[1]. Non-replicas are randomly +rotated (similarly to a round robin with a random index).

      +
      + +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/load-balancing/load-balancing.html b/main/load-balancing/load-balancing.html new file mode 100644 index 0000000000..6eafa9d5b1 --- /dev/null +++ b/main/load-balancing/load-balancing.html @@ -0,0 +1,736 @@ + + + + + + + + + + + + + Load balancing | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Load balancing

      +
      +

      Introduction

      +

      The driver uses a load balancing policy to determine which node(s) and shard(s) +to contact when executing a query. Load balancing policies implement the +LoadBalancingPolicy trait, which contains methods to generate a load +balancing plan based on the query information and the state of the cluster.

      +

      Load balancing policies do not influence to which nodes connections are +being opened. For a node connection blacklist configuration refer to +scylla::transport::host_filter::HostFilter, which can be set session-wide +using SessionBuilder::host_filter method.

      +

      In this chapter, “target” will refer to a pair <node, optional shard>.

      +
      +
      +

      Plan

      +

      When a query is prepared to be sent to the database, the load balancing policy +constructs a load balancing plan. This plan is essentially a list of targets to +which the driver will try to send the query. The first elements of the plan are +the targets which are the best to contact (e.g. they might be replicas for the +requested data or have the best latency).

      +
      +
      +

      Policy

      +

      The Scylla/Cassandra driver provides a default load balancing policy (see +Default Policy for details), but you can +also implement your own custom policies that better suit your specific use +case. To use a custom policy, you simply need to implement the +LoadBalancingPolicy trait and pass an instance of your custom policy to the +used execution profile.

      +

      Our recommendation is to use Default Policy with token- +awareness enabled and latency-awareness disabled.

      +
      +
      +

      Configuration

      +

      Load balancing policies can be configured via execution profiles. In the code +sample provided, a new execution profile is created using +ExecutionProfile::builder(), and the load balancing policy is set to the +DefaultPolicy using .load_balancing_policy(policy).

      +

      The newly created execution profile is then converted to a handle using +.into_handle(), and passed as the default execution profile to the +SessionBuilder using .default_execution_profile_handle(handle).

      +
      use scylla::SessionBuilder;
      +use scylla::load_balancing::DefaultPolicy;
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::session::Session;
      +use std::sync::Arc;
      +
      +let policy = Arc::new(DefaultPolicy::default());
      +
      +let profile = ExecutionProfile::builder()
      +    .load_balancing_policy(policy)
      +    .build();
      +let handle = profile.into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node(&uri)
      +    .default_execution_profile_handle(handle)
      +    .build()
      +    .await?;
      +
      +
      +

      In addition to being able to configure load balancing policies through +execution profiles at the session level, the driver also allow for setting +execution profile handles on a per-query basis. This means that for each query, +a specific execution profile can be selected with a customized load balancing +settings.

      +
      +
      +

      LoadBalancingPolicy trait

      +
      +

      pick and fallback:

      +

      Most queries are sent successfully on the first try. In such cases, only the +first element of the load balancing plan is needed, so it’s usually unnecessary +to compute entire load balancing plan. To optimize this common case, the +LoadBalancingPolicy trait provides two methods: pick and fallback.

      +

      pick returns the first target to contact for a given query, which is usually +the best based on a particular load balancing policy.

      +

      fallback, returns an iterator that provides the rest of the targets in the +load balancing plan. fallback is called when using the initial picked +target fails (or when executing speculatively) or when pick returned None.

      +

      It’s possible for the fallback method to include the same target that was +returned by the pick method. In such cases, the query execution layer filters +out the picked target from the iterator returned by fallback.

      +
      +
      +

      on_query_success and on_query_failure:

      +

      The on_query_success and on_query_failure methods are useful for load +balancing policies because they provide feedback on the performance and health +of the nodes in the cluster.

      +

      When a query is successfully executed, the on_query_success method is called +and can be used by the load balancing policy to update its internal state. For +example, a policy might use the latency of the successful query to update its +latency statistics for each node in the cluster. This information can be used +to make decisions about which nodes to contact in the future.

      +

      On the other hand, when a query fails to execute, the on_query_failure method +is called and provides information about the failure. The error message +returned by Cassandra can help determine the cause of the failure, such as a +node being down or overloaded. The load balancing policy can use this +information to update its internal state and avoid contacting the same node +again until it’s recovered.

      +
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/logging/logging.html b/main/logging/logging.html new file mode 100644 index 0000000000..d6bbdb6aee --- /dev/null +++ b/main/logging/logging.html @@ -0,0 +1,651 @@ + + + + + + + + + + + + + Logging | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Logging

      +

      The driver uses the tracing crate for all logs.
      +To view the logs you have to create a tracing subscriber to which all logs will be written.

      +

      To just print the logs you can use the default subscriber:

      +
      use tracing::info;
      +
      +#[tokio::main]
      +async fn main() -> Result<(), Box<dyn Error>> {
      +    // Install global collector configured based on RUST_LOG env var
      +    // This collector will receive logs from the driver
      +    tracing_subscriber::fmt::init();
      +
      +    let uri = std::env::var("SCYLLA_URI")
      +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
      +
      +    info!("Connecting to {}", uri);
      +
      +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
      +    session
      +        .query(
      +            "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \
      +            {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}",
      +            &[],
      +        )
      +        .await?;
      +
      +    // This query should generate a warning message
      +    session.query("USE ks", &[]).await?;
      +
      +    Ok(())
      +}
      +
      +
      +

      To start this example execute:

      +
      RUST_LOG=info cargo run
      +
      +
      +

      The full example is available in the examples folder

      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/metrics/metrics.html b/main/metrics/metrics.html new file mode 100644 index 0000000000..405d4aac7f --- /dev/null +++ b/main/metrics/metrics.html @@ -0,0 +1,655 @@ + + + + + + + + + + + + + Driver metrics | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Driver metrics

      +

      During operation the driver collects various metrics.

      +

      They can be accessed at any moment using Session::get_metrics()

      +
      +

      Collected metrics:

      +
        +
      • Query latencies

      • +
      • Total number of nonpaged queries

      • +
      • Number of errors during nonpaged queries

      • +
      • Total number of paged queries

      • +
      • Number of errors during paged queries

      • +
      • Number of retries

      • +
      +
      +
      +

      Example

      +
      let metrics = session.get_metrics();
      +
      +println!("Queries requested: {}", metrics.get_queries_num());
      +println!("Iter queries requested: {}", metrics.get_queries_iter_num());
      +println!("Errors occurred: {}", metrics.get_errors_num());
      +println!("Iter errors occurred: {}", metrics.get_errors_iter_num());
      +println!("Average latency: {}", metrics.get_latency_avg_ms().unwrap());
      +println!(
      +    "99.9 latency percentile: {}",
      +    metrics.get_latency_percentile_ms(99.9).unwrap()
      +);
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/migration-guides/0.11-serialization.html b/main/migration-guides/0.11-serialization.html new file mode 100644 index 0000000000..a5a7565349 --- /dev/null +++ b/main/migration-guides/0.11-serialization.html @@ -0,0 +1,733 @@ + + + + + + + + + + + + + Adjusting code to changes in serialization API introduced in 0.11 | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Adjusting code to changes in serialization API introduced in 0.11

      +
      +

      Background

      +

      When executing a statement through the CQL protocol, values for the bind markers are sent in a serialized, untyped form. In order to implement a safer and more robust interface, drivers can use the information returned after preparing a statement to check the type of data provided by the user against the actual types of the bind markers.

      +

      Before 0.11, the driver couldn’t do this kind of type checking. For example, in the case of non-batch queries, the only information about the user data it has is that it implements ValueList - defined as follows:

      +
      pub trait ValueList {
      +    fn serialized(&self) -> SerializedResult<'_>;
      +    fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError>;
      +}
      +
      +
      +

      The driver would naively serialize the data and hope that the user took care to send correct types of values. Failing to do so would, in the best case, fail on the DB-side validation; in the worst case, the data in its raw form may be reinterpreted as another type in an unintended manner.

      +

      Another problem is that the information from the prepared statement response is required to robustly serialize user defined types, as UDTs require their fields to be serialized in the same order as they are defined in the database schema. The IntoUserType macro which implements Rust struct -> UDT serialization just expects that the order of the Rust struct fields matches the schema, but ensuring this can be very cumbersome for the users.

      +

      In version 0.11, a new set of traits is introduced and the old ones are deprecated. The new traits receive more information during serialization such as names of the column/bind markers and their types, which allows to fix the issues mentioned in the previous section.

      +
      +
      +

      Old vs. new

      +

      Both the old and the new APIs are based on three core traits:

      +
        +
      • Value - called SerializeCql in the new API. A type that can serialize itself to a single CQL value. For example, i32 serializes itself into a representation that is compatible with the CQL int type.

      • +
      • ValueList - called SerializeRow in the new API. A type that can serialize itself as a list of values for a CQL statement. For example, a (i32, &str) produces a list of two values which can be used in a query with two bind markers, e.g. SELECT * FROM table WHERE pk = ? AND ck = ?. Optionally, values in the produced list may be associated with names which is useful when using it with a query with named bind markers, e.g. SELECT * FROM table WHERE pk = :pk AND ck = :ck.

      • +
      • LegacyBatchValues, previously named BatchValues - in new API replaced with new trait called (again) BatchValues. Represents a source of data for a batch request. It is essentially equivalent to a list of ValueList, one for each statement in the batch. For example, ((1, 2), (3, 4, 5)) can be used for a batch with two statements, the first one having two bind markers and the second one having three.

      • +
      +

      All methods which take one of the old traits were changed to take the new trait - notably, this includes Session::query, (Caching)Session::execute, (Caching)Session::batch.

      +

      The driver comes a set of impls of those traits which allow to represent any CQL type (for example, see Data Types page for a list of for which Value and SerializeCql is implemented). If the driver implements an old trait for some type, then it also provides implements the new trait for the same type.

      +
      +
      +

      Migration scenarios

      +
      +

      Different default behavior in SerializeRow/SerializeCql macros

      +

      By default, the SerializeRow and SerializeCql will match the fields in the Rust struct by name to bind marker names (in case of SerializeRow) or UDT field names (in case of SerializeCql). This is different from the old ValueList and IntoUserType macros which did not look at the field names at all and would expect the user to order the fields correctly. While the new behavior is much more ergonomic, you might have reasons not to use it.

      +
      +

      NOTE: The deserialization macro counterparts FromRow and FromUserType have the same limitation as the old serialization macros - they require struct fields to be properly ordered. While a similar rework is planned for the deserialization traits in a future release, for the time being it might not be worth keeping the column names in sync with the database.

      +
      +

      In order to bring the old behavior to the new macros (the only difference being type checking which cannot be disabled right now) you can configure it using attributes, as shown in the snippet below:

      +
      use scylla::SerializeCql;
      +
      +// The exact same attributes apply to the `SerializeRow` macro and their
      +// effect is completely analogous.
      +#[derive(SerializeCql)]
      +#[scylla(flavor = "enforce_order", skip_name_checks)]
      +struct Person {
      +    name: String,
      +    surname: String,
      +    age: i16,
      +}
      +
      +
      +

      Refer to the API reference page for the SerializeRow and SerializeCql macros in the scylla crate to learn more about the supported attributes and their meaning.

      +
      +
      +

      Preparing is mandatory with a non-empty list of values

      +
      +

      NOTE: The considerations in this section only concerns users of the Session API, CachingSession is not affected as it already does preparation before execute and caches the result.

      +
      +

      As explained in the Background section, the driver uses data returned from the database after preparing a statement in order to implement type checking. As the new API makes type checking mandatory, the driver must prepare the statement so that the data for the bind markers can be type checked. It is done in case of the existing methods which used to send unprepared statements: Session::query and Session::batch.

      +
      +

      NOTE: The driver will skip preparation if it detects that the list of values for the statement is empty, as there is nothing to be type checked.

      +
      +

      If you send simple statements along with non-empty lists of values, the slowdown will be as follows:

      +
        +
      • For Session::query, the driver will prepare the statement before sending it, incurring an additional round-trip.

      • +
      • For Session::batch, the driver will send a prepare request for each unique unprepared statement with a non-empty list of values. This is done serially!

      • +
      +

      In both cases, if the additional roundtrips are unacceptable, you should prepare the statements beforehand and reuse them - which aligns with our general recommendation against use of simple statements in performance sensitive scenarios.

      +
      +
      +

      Migrating from old to new traits gradually

      +

      In some cases, migration will be as easy as changing occurrences of IntoUserType to SerializeCql and ValueList to SerializeRow and adding some atributes for procedural macros. However, if you have a large enough codebase or some custom, complicated implementations of the old traits then you might not want to migrate everything at once. To support gradual migration, the old traits were not removed but rather deprecated, and we introduced some additional utilities.

      +
      +

      Converting an object implementing an old trait to a new trait

      +

      We provide a number of newtype wrappers:

      +
        +
      • ValueAdapter - implements SerializeCql if the type wrapped over implements Value,

      • +
      • ValueListAdapter - implements SerializeRow if the type wrapped over implements ValueList,

      • +
      • LegacyBatchValuesAdapter - implements BatchValues if the type wrapped over implements LegacyBatchValues.

      • +
      +

      Note that these wrappers are not zero cost and incur some overhead: in case of ValueAdapter and ValueListAdapter, the data is first written into a newly allocated buffer and then rewritten to the final buffer. In case of LegacyBatchValuesAdapter there shouldn’t be any additional allocations unless the implementation has an efficient, non-default Self::LegacyBatchValuesIterator::write_next_to_request implementation (which is not the case for the built-in impls).

      +

      Naturally, the implementations provided by the wrappers are not type safe as they directly use methods from the old traits.

      +

      Conversion in the other direction is not possible.

      +
      +
      +

      Custom implementations of old traits

      +

      It is possible to directly generate an impl of SerializeRow and SerializeCql on a type which implements, respectively, ValueList or Value, without using the wrappers from the previous section. The following macros are provided:

      +
        +
      • impl_serialize_cql_via_value - implements SerializeCql if the type wrapped over implements Value,

      • +
      • impl_serialize_row_via_value_list - implements SerializeRow if the type wrapped over implements ValueList,

      • +
      +

      The implementations are practically as those generated by the wrappers described in the previous section.

      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/migration-guides/migration-guides.html b/main/migration-guides/migration-guides.html new file mode 100644 index 0000000000..5b932cd3a9 --- /dev/null +++ b/main/migration-guides/migration-guides.html @@ -0,0 +1,619 @@ + + + + + + + + + + + + + Migration guides | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Migration guides

      + +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/objects.inv b/main/objects.inv new file mode 100644 index 0000000000..5d605ef479 Binary files /dev/null and b/main/objects.inv differ diff --git a/main/queries/batch.html b/main/queries/batch.html new file mode 100644 index 0000000000..d96521a689 --- /dev/null +++ b/main/queries/batch.html @@ -0,0 +1,756 @@ + + + + + + + + + + + + + Batch statement | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Batch statement

      +

      A batch statement allows to execute many data-modifying statements at once.
      +These statements can be simple or prepared.
      +Only INSERT, UPDATE and DELETE statements are allowed.

      +
      use scylla::batch::Batch;
      +use scylla::query::Query;
      +use scylla::prepared_statement::PreparedStatement;
      +
      +// Create a batch statement
      +let mut batch: Batch = Default::default();
      +
      +// Add a simple statement to the batch using its text
      +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(1, 2)");
      +
      +// Add a simple statement created manually to the batch
      +let simple: Query = Query::new("INSERT INTO ks.tab (a, b) VALUES(3, 4)");
      +batch.append_statement(simple);
      +
      +// Add a prepared statement to the batch
      +let prepared: PreparedStatement = session
      +    .prepare("INSERT INTO ks.tab (a, b) VALUES(?, 6)")
      +    .await?;
      +batch.append_statement(prepared);
      +
      +// Specify bound values to use with each statement
      +let batch_values = ((),
      +                    (),
      +                    (5_i32,));
      +
      +// Run the batch
      +session.batch(&batch, batch_values).await?;
      +
      +
      +
      +

      Warning
      +Using simple statements with bind markers in batches is strongly discouraged. +For each simple statement with a non-empty list of values in the batch, +the driver will send a prepare request, and it will be done sequentially. +Results of preparation are not cached between Session::batch calls. +Consider preparing the statements before putting them into the batch.

      +
      +
      +

      Preparing a batch

      +

      Instead of preparing each statement individually, it’s possible to prepare a whole batch at once:

      +
      use scylla::batch::Batch;
      +
      +// Create a batch statement with unprepared statements
      +let mut batch: Batch = Default::default();
      +batch.append_statement("INSERT INTO ks.simple_unprepared1 VALUES(?, ?)");
      +batch.append_statement("INSERT INTO ks.simple_unprepared2 VALUES(?, ?)");
      +
      +// Prepare all statements in the batch at once
      +let prepared_batch: Batch = session.prepare_batch(&batch).await?;
      +
      +// Specify bound values to use with each statement
      +let batch_values = ((1_i32, 2_i32),
      +                    (3_i32, 4_i32));
      +
      +// Run the prepared batch
      +session.batch(&prepared_batch, batch_values).await?;
      +
      +
      +
      +
      +

      Batch options

      +

      You can set various options by operating on the Batch object.
      +For example to change consistency:

      +
      use scylla::batch::Batch;
      +use scylla::statement::Consistency;
      +
      +// Create a batch
      +let mut batch: Batch = Default::default();
      +batch.append_statement("INSERT INTO ks.tab(a) VALUES(16)");
      +
      +// Set batch consistency to One
      +batch.set_consistency(Consistency::One);
      +
      +// Run the batch
      +session.batch(&batch, ((), )).await?;
      +
      +
      +

      See Batch API documentation +for more options

      +
      +
      +

      Batch values

      +

      Batch takes a tuple of values specified just like in simple or prepared queries.

      +

      Length of batch values must be equal to the number of statements in a batch.
      +Each statement must have its values specified, even if they are empty.

      +

      Values passed to Session::batch must implement the trait BatchValues.
      +By default this includes tuples () and slices &[] of tuples and slices which implement ValueList.

      +

      Example:

      +
      use scylla::batch::Batch;
      +
      +let mut batch: Batch = Default::default();
      +
      +// A statement with two bound values
      +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(?, ?)");
      +
      +// A statement with one bound value
      +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(3, ?)");
      +
      +// A statement with no bound values
      +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(5, 6)");
      +
      +// Batch values is a tuple of 3 tuples containing values for each statement
      +let batch_values = ((1_i32, 2_i32), // Tuple with two values for the first statement
      +                    (4_i32,),       // Tuple with one value for the second statement
      +                    ());            // Empty tuple/unit for the third statement
      +
      +// Run the batch
      +// Note that the driver will prepare the first two statements, due to them
      +// not being prepared and having a non-empty list of values.
      +session.batch(&batch, batch_values).await?;
      +
      +
      +

      For more information about sending values in a statement see Query values

      +
      +
      +

      Performance

      +

      Batch statements do not use token/shard aware load balancing, batches are sent to a random node.

      +

      Use prepared queries for best performance

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/lwt.html b/main/queries/lwt.html new file mode 100644 index 0000000000..cc01f2caec --- /dev/null +++ b/main/queries/lwt.html @@ -0,0 +1,652 @@ + + + + + + + + + + + + + Lightweight transaction (LWT) query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Lightweight transaction (LWT) query

      +

      A lightweight transaction query can be expressed just like any other query, via Session, with the notable difference of having an additional consistency level parameter - the serial_consistency_level.

      +
      +

      Format of the query

      +

      A lightweight transaction query is not a separate type - it can be expressed just like any other queries: via SimpleQuery, PreparedStatement, batches, and so on. The difference lays in the query string itself - when it contains a condition (e.g. IF NOT EXISTS), it becomes a lightweight transaction. It’s important to remember that CQL specification requires a separate, additional consistency level to be defined for LWT queries - serial_consistency_level. The serial consistency level can only be set to two values: SerialConsistency::Serial or SerialConsistency::LocalSerial. The “local” variant makes the transaction consistent only within the same datacenter. For convenience, Scylla Rust Driver sets the default consistency level to LocalSerial, as it’s more commonly used. For cross-datacenter consistency, please remember to always override the default with SerialConsistency::Serial.

      +
      use scylla::query::Query;
      +use scylla::statement::{Consistency, SerialConsistency};
      +
      +// Create a Query manually to change the Consistency to ONE
      +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?) IF NOT EXISTS".to_string());
      +my_query.set_consistency(Consistency::One);
      +// Use cross-datacenter serial consistency
      +my_query.set_serial_consistency(Some(SerialConsistency::Serial));
      +
      +// Insert a value into the table
      +let to_insert: i32 = 12345;
      +session.query(my_query, (to_insert,)).await?;
      +
      +
      +

      The rest of the API remains identical for LWT and non-LWT queries.

      +

      See Query API documentation for more options

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/paged.html b/main/queries/paged.html new file mode 100644 index 0000000000..061b6c082b --- /dev/null +++ b/main/queries/paged.html @@ -0,0 +1,750 @@ + + + + + + + + + + + + + Paged query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Paged query

      +

      Sometimes query results might not fit in a single page. Paged queries +allow to receive the whole result page by page.

      +

      Session::query_iter and Session::execute_iter take a simple query or a prepared query +and return an async iterator over result Rows.

      +
      +

      Warning
      +In case of unprepared variant (Session::query_iter) if the values are not empty +driver will first fully prepare a query (which means issuing additional request to each +node in a cluster). This will have a performance penalty - how big it is depends on +the size of your cluster (more nodes - more requests) and the size of returned +result (more returned pages - more amortized penalty). In any case, it is preferable to +use Session::execute_iter.

      +
      +
      +

      Examples

      +

      Use query_iter to perform a simple query with paging:

      +
      use scylla::IntoTypedRows;
      +use futures::stream::StreamExt;
      +
      +let mut rows_stream = session
      +    .query_iter("SELECT a, b FROM ks.t", &[])
      +    .await?
      +    .into_typed::<(i32, i32)>();
      +
      +while let Some(next_row_res) = rows_stream.next().await {
      +    let (a, b): (i32, i32) = next_row_res?;
      +    println!("a, b: {}, {}", a, b);
      +}
      +
      +
      +

      Use execute_iter to perform a prepared query with paging:

      +
      use scylla::IntoTypedRows;
      +use scylla::prepared_statement::PreparedStatement;
      +use futures::stream::StreamExt;
      +
      +let prepared: PreparedStatement = session
      +    .prepare("SELECT a, b FROM ks.t")
      +    .await?;
      +
      +let mut rows_stream = session
      +    .execute_iter(prepared, &[])
      +    .await?
      +    .into_typed::<(i32, i32)>();
      +
      +while let Some(next_row_res) = rows_stream.next().await {
      +    let (a, b): (i32, i32) = next_row_res?;
      +    println!("a, b: {}, {}", a, b);
      +}
      +
      +
      +

      Query values can be passed to query_iter and execute_iter just like in a simple query

      +
      +
      +

      Configuring page size

      +

      It’s possible to configure the size of a single page.

      +

      On a Query:

      +
      use scylla::query::Query;
      +
      +let mut query: Query = Query::new("SELECT a, b FROM ks.t");
      +query.set_page_size(16);
      +
      +let _ = session.query_iter(query, &[]).await?; // ...
      +
      +
      +

      On a PreparedStatement:

      +
      use scylla::prepared_statement::PreparedStatement;
      +
      +let mut prepared: PreparedStatement = session
      +    .prepare("SELECT a, b FROM ks.t")
      +    .await?;
      +
      +prepared.set_page_size(16);
      +
      +let _ = session.execute_iter(prepared, &[]).await?; // ...
      +
      +
      +
      +
      +

      Passing the paging state manually

      +

      It’s possible to fetch a single page from the table, extract the paging state +from the result and manually pass it to the next query. That way, the next +query will start fetching the results from where the previous one left off.

      +

      On a Query:

      +
      use scylla::query::Query;
      +
      +let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6);
      +let res1 = session.query(paged_query.clone(), &[]).await?;
      +let res2 = session
      +    .query_paged(paged_query.clone(), &[], res1.paging_state)
      +    .await?;
      +
      +
      +
      +

      Warning
      +If the values are not empty, driver first needs to send a PREPARE request +in order to fetch information required to serialize values. This will affect +performance because 2 round trips will be required instead of 1.

      +
      +

      On a PreparedStatement:

      +
      use scylla::query::Query;
      +
      +let paged_prepared = session
      +    .prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7))
      +    .await?;
      +let res1 = session.execute(&paged_prepared, &[]).await?;
      +let res2 = session
      +    .execute_paged(&paged_prepared, &[], res1.paging_state)
      +    .await?;
      +
      +
      +
      +
      +

      Performance

      +

      Performance is the same as in non-paged variants.
      +For the best performance use prepared queries.

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/prepared.html b/main/queries/prepared.html new file mode 100644 index 0000000000..fd5d5289a8 --- /dev/null +++ b/main/queries/prepared.html @@ -0,0 +1,745 @@ + + + + + + + + + + + + + Prepared query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Prepared query

      +

      Prepared queries provide much better performance than simple queries, +but they need to be prepared before use.

      +

      Benefits that prepared statements have to offer:

      +
        +
      • Type safety - thanks to metadata provided by the server, the driver can verify bound values’ types before serialization. This way, we can be always sure that the Rust type provided by the user is compatible (and if not, the error is returned) with the destined native type. The same applies for deserialization.

      • +
      • Performance - when executing a simple query with non-empty values list, the driver +prepares the statement before execution. The reason for this is to provide type safety for simple queries. However, this implies 2 round trips per simple query execution. On the other hand, the cost of prepared statement’s execution is only 1 round trip.

      • +
      • Improved load-balancing - using the statement metadata, the driver can compute a set of destined replicas for current statement execution. These replicas will be preferred when choosing the node (and shard) to send the request to. For more insight on this, see performance section.

      • +
      +
      use scylla::prepared_statement::PreparedStatement;
      +
      +// Prepare the query for later execution
      +let prepared: PreparedStatement = session
      +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
      +    .await?;
      +
      +// Run the prepared query with some values, just like a simple query
      +let to_insert: i32 = 12345;
      +session.execute(&prepared, (to_insert,)).await?;
      +
      +
      +
      +

      Warning
      +For token/shard aware load balancing to work properly, all partition key values +must be sent as bound values (see performance section)

      +
      +
      +

      Warning
      +Don’t use execute to receive large amounts of data.
      +By default the query is unpaged and might cause heavy load on the cluster. +In such cases set a page size and use a paged query instead.

      +

      When page size is set, execute will return only the first page of results.

      +
      +
      +

      Session::prepare

      +

      Session::prepare takes query text and prepares the query on all nodes and shards. +If at least one succeeds returns success.

      +
      +
      +

      Session::execute

      +

      Session::execute takes a prepared query and bound values and runs the query. +Passing values and the result is the same as in simple query.

      +
      +
      +

      Query options

      +

      To specify custom options, set them on the PreparedStatement before execution. +For example to change the consistency:

      +
      use scylla::prepared_statement::PreparedStatement;
      +use scylla::statement::Consistency;
      +
      +// Prepare the query for later execution
      +let mut prepared: PreparedStatement = session
      +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
      +    .await?;
      +
      +// Set prepared query consistency to One
      +// This is the consistency with which this query will be executed
      +prepared.set_consistency(Consistency::One);
      +
      +// Run the prepared query with some values, just like a simple query
      +let to_insert: i32 = 12345;
      +session.execute(&prepared, (to_insert,)).await?;
      +
      +
      +

      See PreparedStatement API documentation +for more options.

      +
      +

      Note +Prepared statements can be created from Query structs and will inherit from +the custom options that the Query was created with. +This is especially useful when using CachingSession::execute for example.

      +
      +
      +
      +

      Performance

      +

      Prepared queries have good performance, much better than simple queries. +By default they use shard/token aware load balancing.

      +
      +

      Always pass partition key values as bound values. +Otherwise the driver can’t hash them to compute partition key +and they will be sent to the wrong node, which worsens performance.

      +
      +

      Let’s say we have a table like this:

      +
      TABLE ks.prepare_table (
      +    a int,
      +    b int,
      +    c int,
      +    PRIMARY KEY (a, b)
      +)
      +
      +
      +
      use scylla::prepared_statement::PreparedStatement;
      +
      +// WRONG - partition key value is passed in query string
      +// Load balancing will compute the wrong partition key
      +let wrong_prepared: PreparedStatement = session
      +    .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(12345, ?, 16)")
      +    .await?;
      +
      +session.execute(&wrong_prepared, (54321,)).await?;
      +
      +// GOOD - partition key values are sent as bound values
      +// Other values can be sent any way you like, it doesn't matter
      +let good_prepared: PreparedStatement = session
      +    .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(?, ?, 16)")
      +    .await?;
      +
      +session.execute(&good_prepared, (12345, 54321)).await?;
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/queries.html b/main/queries/queries.html new file mode 100644 index 0000000000..3e35c36fbf --- /dev/null +++ b/main/queries/queries.html @@ -0,0 +1,648 @@ + + + + + + + + + + + + + Making queries | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Making queries

      +

      This driver supports all query types available in Scylla:

      +
        +
      • Simple queries

        +
          +
        • Easy to use

        • +
        • Poor performance

        • +
        • Primitive load balancing

        • +
        +
      • +
      • Prepared queries

        +
          +
        • Need to be prepared before use

        • +
        • Fast

        • +
        • Properly load balanced

        • +
        +
      • +
      • Batch statements

        +
          +
        • Run multiple queries at once

        • +
        • Can be prepared for better performance and load balancing

        • +
        +
      • +
      • Paged queries

        +
          +
        • Allows to read result in multiple pages when it doesn’t fit in a single response

        • +
        • Can be prepared for better performance and load balancing

        • +
        +
      • +
      +

      Additionally there is special functionality to enable USE KEYSPACE queries: +USE keyspace

      +

      Queries are fully asynchronous - you can run as many of them in parallel as you wish.

      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/result.html b/main/queries/result.html new file mode 100644 index 0000000000..7aef3ffdd7 --- /dev/null +++ b/main/queries/result.html @@ -0,0 +1,758 @@ + + + + + + + + + + + + + Query result | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Query result

      +

      Session::query and Session::execute return a QueryResult with rows represented as Option<Vec<Row>>.

      +
      +

      Basic representation

      +

      Row is a basic representation of a received row. It can be used by itself, but it’s a bit awkward to use:

      +
      if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
      +    for row in rows {
      +        let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap();
      +    }
      +}
      +
      +
      +
      +
      +

      Parsing using into_typed

      +

      The driver provides a way to parse a row as a tuple of Rust types:

      +
      use scylla::IntoTypedRows;
      +
      +// Parse row as a single column containing an int value
      +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
      +    for row in rows {
      +        let (int_value,): (i32,) = row.into_typed::<(i32,)>()?;
      +    }
      +}
      +
      +// rows.into_typed() converts a Vec of Rows to an iterator of parsing results
      +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
      +    for row in rows.into_typed::<(i32,)>() {
      +        let (int_value,): (i32,) = row?;
      +    }
      +}
      +
      +// Parse row as two columns containing an int and text columns
      +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
      +    for row in rows.into_typed::<(i32, String)>() {
      +        let (int_value, text_value): (i32, String) = row?;
      +    }
      +}
      +
      +
      +
      +
      +

      Parsing using convenience methods

      +

      QueryResult provides convenience methods for parsing rows. +Here are a few of them:

      +
        +
      • rows_typed::<RowT>() - returns the rows parsed as the given type

      • +
      • maybe_first_row_typed::<RowT> - returns Option<RowT> containing first row from the result

      • +
      • first_row_typed::<RowT> - same as maybe_first_row, but fails without the first row

      • +
      • single_row_typed::<RowT> - same as first_row, but fails when there is more than one row

      • +
      • result_not_rows() - ensures that query response was not rows, helps avoid bugs

      • +
      +
      // Parse row as a single column containing an int value
      +let rows = session
      +    .query("SELECT a from ks.tab", &[])
      +    .await?
      +    .rows_typed::<(i32,)>()?; // Same as .rows()?.into_typed()
      +for row in rows {
      +    let (int_value,): (i32,) = row?;
      +}
      +
      +// maybe_first_row_typed gets the first row and parses it as the given type
      +let first_int_val: Option<(i32,)> = session
      +    .query("SELECT a from ks.tab", &[])
      +    .await?
      +    .maybe_first_row_typed::<(i32,)>()?;
      +
      +// no_rows fails when the response is rows
      +session.query("INSERT INTO ks.tab (a) VALUES (0)", &[]).await?.result_not_rows()?;
      +
      +
      +

      For more see QueryResult

      +
      +

      NULL values

      +

      NULL values will return an error when parsed as a Rust type. +To properly handle NULL values parse column as an Option<>:

      +
      use scylla::IntoTypedRows;
      +
      +// Parse row as two columns containing an int and text which might be null
      +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
      +    for row in rows.into_typed::<(i32, Option<String>)>() {
      +        let (int_value, str_or_null): (i32, Option<String>) = row?;
      +    }
      +}
      +
      +
      +
      +
      +

      Parsing row as a custom struct

      +

      It is possible to receive row as a struct with fields matching the columns.
      +The struct must:

      +
        +
      • have the same number of fields as the number of queried columns

      • +
      • have field types matching the columns being received

      • +
      • derive FromRow

      • +
      +

      Field names don’t need to match column names.

      +
      use scylla::IntoTypedRows;
      +use scylla::macros::FromRow;
      +use scylla::frame::response::cql_to_rust::FromRow;
      +
      +#[derive(FromRow)]
      +struct MyRow {
      +    age: i32,
      +    name: Option<String>
      +}
      +
      +// Parse row as two columns containing an int and text which might be null
      +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
      +    for row in rows.into_typed::<MyRow>() {
      +        let my_row: MyRow = row?;
      +    }
      +}
      +
      +
      +
      +
      +

      Other data types

      +

      For parsing other data types see Data Types

      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/schema-agreement.html b/main/queries/schema-agreement.html new file mode 100644 index 0000000000..c00f61d6e1 --- /dev/null +++ b/main/queries/schema-agreement.html @@ -0,0 +1,681 @@ + + + + + + + + + + + + + Schema agreement | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Schema agreement

      +

      Sometimes after performing queries some nodes have not been updated, so we need a mechanism that checks if every node have agreed on schema version.

      +
      +

      Automated awaiting schema agreement

      +

      The driver automatically awaits schema agreement after a schema-altering query is executed. +Waiting for schema agreement more than necessary is never a bug, but might slow down applications which do a lot of schema changes (e.g. a migration). +For instance, in case where somebody wishes to create a keyspace and then a lot of tables in it, it makes sense only to wait after creating a keyspace +and after creating all the tables rather than after every query. Therefore, the said behaviour can be disabled:

      +
      let session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .auto_await_schema_agreement(false)
      +    .build()
      +    .await?;
      +
      +
      +
      +
      +

      Manually awaiting schema agreement

      +

      Session::await_schema_agreement returns a Future that can be awaited as long as schema is not in an agreement. +However, it won’t wait forever; SessionConfig defines a timeout that limits the time of waiting. If the timeout elapses, +the return value is Err(QueryError::RequestTimeout), otherwise it is Ok(schema_version).

      +
      session.await_schema_agreement().await?;
      +
      +
      +
      +
      +

      Interval of checking for schema agreement

      +

      If the schema is not agreed upon, the driver sleeps for a duration before checking it again. The default value is 200 milliseconds, +but it can be changed with SessionBuilder::schema_agreement_interval.

      +
      SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .schema_agreement_interval(Duration::from_secs(1))
      +    .build()
      +    .await?;
      +
      +
      +
      +
      +

      Checking if schema is in agreement now

      +

      If you want to check if schema is in agreement now, without retrying after failure, you can use Session::check_schema_agreement function.

      +
      if session.check_schema_agreement().await?.is_some() {
      +    println!("SCHEMA AGREED");
      +} else {
      +    println!("SCHEMA IS NOT IN AGREEMENT");
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/simple.html b/main/queries/simple.html new file mode 100644 index 0000000000..695d52cb45 --- /dev/null +++ b/main/queries/simple.html @@ -0,0 +1,718 @@ + + + + + + + + + + + + + Simple query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Simple query

      +

      Simple query takes query text and values and simply executes them on a Session:

      +
      // Insert a value into the table
      +let to_insert: i32 = 12345;
      +session
      +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
      +    .await?;
      +
      +
      +
      +

      Warning
      +Don’t use simple query to receive large amounts of data.
      +By default the query is unpaged and might cause heavy load on the cluster.
      +In such cases set a page size and use paged query instead.\

      +

      When page size is set, query will return only the first page of results.

      +
      +
      +

      Warning
      +If the values are not empty, driver first needs to send a PREPARE request +in order to fetch information required to serialize values. This will affect +performance because 2 round trips will be required instead of 1.

      +
      +
      +

      First argument - the query

      +

      As the first argument Session::query takes anything implementing Into<Query>.
      +You can create a query manually to set custom options. For example to change query consistency:

      +
      use scylla::query::Query;
      +use scylla::statement::Consistency;
      +
      +// Create a Query manually to change the Consistency to ONE
      +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
      +my_query.set_consistency(Consistency::One);
      +
      +// Insert a value into the table
      +let to_insert: i32 = 12345;
      +session.query(my_query, (to_insert,)).await?;
      +
      +
      +

      See Query API documentation for more options

      +
      +
      +

      Second argument - the values

      +

      Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.
      +Each ? in query text will be filled with the matching value.

      +

      The easiest way is to pass values using a tuple:

      +
      // Sending an integer and a string using a tuple
      +session
      +    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, 'text2')", (2_i32, "Some text"))
      +    .await?;
      +
      +
      +

      Here the first ? will be filled with 2 and the second with "Some text".

      +
      +

      Never pass values by adding strings, this could lead to SQL Injection

      +
      +

      See Query values for more information about sending values in queries

      +
      +
      +

      Query result

      +

      Session::query returns QueryResult with rows represented as Option<Vec<Row>>.
      +Each row can be parsed as a tuple of rust types using rows_typed:

      +
      use scylla::IntoTypedRows;
      +
      +// Query rows from the table and print them
      +let result = session.query("SELECT a FROM ks.tab", &[]).await?;
      +let mut iter = result.rows_typed::<(i32,)>()?;
      +while let Some(read_row) = iter.next().transpose()? {
      +    println!("Read a value from row: {}", read_row.0);
      +}
      +
      +
      +
      +

      In cases where page size is set, simple query returns only a single page of results.
      +To receive all pages use a paged query instead.\

      +
      +

      See Query result for more information about handling query results

      +
      +
      +

      Performance

      +

      Simple queries should not be used in places where performance matters.
      +If performance matters use a Prepared query instead.

      +

      With simple query the database has to parse query text each time it’s executed, which worsens performance.\

      +

      Additionally token and shard aware load balancing does not work with simple queries. They are sent to random nodes.

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/timeouts.html b/main/queries/timeouts.html new file mode 100644 index 0000000000..70ab8e3a93 --- /dev/null +++ b/main/queries/timeouts.html @@ -0,0 +1,667 @@ + + + + + + + + + + + + + Query timeouts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Query timeouts

      +

      Query execution time can be limited by setting a request timeout. If a query does not complete +in the given time, then QueryError::RequestTimeout is returned by the driver immediately, +so that application logic can continue operating, but the query may still be in progress on the server.

      +

      As a side note, if one wishes custom server-side timeouts (i.e. actual interruption of query processing), +one can use aUSING TIMEOUT <duration> directive supported in ScyllaDB +(but not in Cassandra).

      +

      Timeout can be set globally (per session) or locally (for given statement). +The default per-session timeout is currently 30s. +It is possible to turn off timeouts completely by providing None as timeout when building Session. +However, setting per-statement timeout to None results in falling back to per-session timeout.

      +
      use scylla::{Session, SessionBuilder, query::Query};
      +use scylla::transport::ExecutionProfile;
      +use std::time::Duration;
      +
      +let uri = std::env::var("SCYLLA_URI")
      +    .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
      +
      +let no_timeout_profile_handle = ExecutionProfile::builder()
      +    .request_timeout(None) // no timeout
      +    .build()
      +    .into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node(uri)
      +    .default_execution_profile_handle(no_timeout_profile_handle) // no per-session timeout
      +    .build()
      +    .await?;
      +
      +// This query, having no timeout, could block indefinitely if a queried node hangs.
      +session
      +    .query("TRUNCATE keyspace.table", ())
      +    .await?;
      +
      +let three_sec_timeout_profile_handle = ExecutionProfile::builder()
      +    .request_timeout(Some(Duration::from_secs(3))) // no timeout
      +    .build()
      +    .into_handle();
      +
      +// The below query will last for no more than 3 seconds, yielding a RequestTimeout error
      +// if no response arrives until then.
      +let mut query: Query = "TRUNCATE keyspace.table".into();
      +query.set_execution_profile_handle(Some(three_sec_timeout_profile_handle));
      +session
      +    .query(query, ())
      +    .await?;
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/usekeyspace.html b/main/queries/usekeyspace.html new file mode 100644 index 0000000000..9526d78708 --- /dev/null +++ b/main/queries/usekeyspace.html @@ -0,0 +1,701 @@ + + + + + + + + + + + + + USE keyspace | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      USE keyspace

      +

      Using a keyspace allows to omit keyspace name in queries.

      +

      For example in cqlsh one could write:

      +
      cqlsh> SELECT * FROM my_keyspace.table;
      +
      + a     | b     |
      +-------+-------+
      + 12345 | 54321 |
      +
      +(1 rows)
      +cqlsh> USE my_keyspace;
      +cqlsh:my_keyspace> SELECT * FROM table;
      +
      + a     | b     |
      +-------+-------+
      + 12345 | 54321 |
      +
      +(1 rows)
      +
      +
      +

      Tables from other keyspaces can still easily be accessed by using their keyspace names.

      +
      cqlsh:my_keyspace> SELECT * FROM other_keyspace.other_table;
      +
      +
      +

      In the driver this can be achieved using Session::use_keyspace:

      +
      session
      +    .query("INSERT INTO my_keyspace.tab (a) VALUES ('test1')", &[])
      +    .await?;
      +
      +session.use_keyspace("my_keyspace", false).await?;
      +
      +// Now we can omit keyspace name in the query
      +session
      +    .query("INSERT INTO tab (a) VALUES ('test2')", &[])
      +    .await?;
      +
      +
      +

      The first argument is the keyspace name.
      +The second argument states whether this name is case sensitive.

      +

      It is also possible to send raw use keyspace query using Session::query instead of Session::use_keyspace such as:

      +
      session.query("USE my_keyspace", &[]).await?;
      +
      +
      +

      This method has a slightly worse latency than Session::use_keyspace - there are two roundtrips needed instead of one. +Therefore, Session::use_keyspace is the preferred method for setting keyspaces.

      +
      +

      Multiple use queries at once

      +

      Don’t run multiple use_keyspace queries at once. +This could end up with half of connections using one keyspace and the other half using the other.

      +
      +
      +

      Case sensitivity

      +

      In CQL a keyspace name can be case insensitive (without ") or case sensitive (with ").
      +If the second argument to use_keyspace is set to true this keyspace name will be wrapped in ".
      +It is best to avoid the problem altogether and just not create two keyspaces with the same name but different cases.

      +

      Let’s see what happens when there are two keyspaces with the same name but different cases: my_keyspace and MY_KEYSPACE:

      +
      // lowercase name without case sensitivity will use my_keyspace
      +session.use_keyspace("my_keyspace", false).await?;
      +
      +// lowercase name with case sensitivity will use my_keyspace
      +session.use_keyspace("my_keyspace", true).await?;
      +
      +// uppercase name without case sensitivity will use my_keyspace
      +session.use_keyspace("MY_KEYSPACE", false).await?;
      +
      +// uppercase name with case sensitivity will use MY_KEYSPACE
      +session.use_keyspace("MY_KEYSPACE", true).await?;
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/queries/values.html b/main/queries/values.html new file mode 100644 index 0000000000..198c35fc8b --- /dev/null +++ b/main/queries/values.html @@ -0,0 +1,757 @@ + + + + + + + + + + + + + Query values | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Query values

      +

      Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.
      +Each ? in query text will be filled with the matching value.

      +
      +

      Never pass values by adding strings, this could lead to SQL Injection

      +
      +

      Each list of values to send in a query must implement the trait SerializeRow.
      +By default this can be a slice &[], a tuple () (max 16 elements) of values to send, +or a custom struct which derives from SerializeRow.

      +

      A few examples:

      +
      // Empty slice means that there are no values to send
      +session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?;
      +
      +// Empty tuple/unit also means that there are no values to send
      +session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?;
      +
      +// Sending three integers using a slice:
      +session
      +    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref())
      +    .await?;
      +
      +// Sending an integer and a string using a tuple
      +session
      +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text"))
      +    .await?;
      +
      +// Sending an integer and a string using a named struct.
      +// Names of fields must match names of columns in request,
      +// but having them in the same order is not required.
      +// If the fields are in the same order, you can use attribute:
      +// `#[scylla(flavor = "enforce_order")]`
      +// in order to skip sorting the fields and just check if they
      +// are in the same order. See documentation of this macro
      +// for more information.
      +#[derive(SerializeRow)]
      +struct IntString {
      +    a: i32,
      +    b: String,
      +}
      +
      +let int_string = IntString {
      +    a: 42_i32,
      +    b: "hello".to_owned(),
      +};
      +
      +session
      +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string)
      +    .await?;
      +
      +// You can use named bind markers in query if you want
      +// your names in struct to be different than column names.
      +#[derive(SerializeRow)]
      +struct IntStringCustom {
      +    first_value: i32,
      +    second_value: String,
      +}
      +
      +let int_string_custom = IntStringCustom {
      +    first_value: 42_i32,
      +    second_value: "hello".to_owned(),
      +};
      +
      +session
      +    .query("INSERT INTO ks.tab (a, b) VALUES(:first_value, :second_value)", int_string_custom)
      +    .await?;
      +
      +// Sending a single value as a tuple requires a trailing coma (Rust syntax):
      +session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?;
      +
      +// Each value can also be sent using a reference:
      +session
      +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text"))
      +    .await?;
      +
      +// A map of named values can also be provided:
      +let mut vals: HashMap<&str, CqlValue> = HashMap::new();
      +vals.insert("avalue", CqlValue::Text("hello".to_string()));
      +vals.insert("bvalue", CqlValue::Int(17));
      +session
      +    .query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals)
      +    .await?;
      +
      +
      +
      +

      NULL values

      +

      Null values can be sent using Option<> - sending a None will make the value NULL:

      +
      let null_i32: Option<i32> = None;
      +session
      +    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
      +    .await?;
      +
      +
      +
      +
      +

      Unset values

      +

      When performing an insert with values which might be NULL, it’s better to use Unset.
      +Database treats inserting NULL as a delete operation and will generate a tombstone. +Using Unset results in better performance:

      +
      use scylla::frame::value::{MaybeUnset, Unset};
      +
      +// Inserting a null results in suboptimal performance
      +let null_i32: Option<i32> = None;
      +session
      +    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
      +    .await?;
      +
      +// Using MaybeUnset enum is better
      +let unset_i32: MaybeUnset<i32> = MaybeUnset::Unset;
      +session
      +    .query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,))
      +    .await?;
      +
      +// If we are sure that a value should be unset we can simply use Unset
      +session
      +    .query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,))
      +    .await?;
      +
      +
      +

      See the issue for more information about Unset

      +
      +
      +

      Other data types

      +

      See Data Types for instructions on sending other data types

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/quickstart/create-project.html b/main/quickstart/create-project.html new file mode 100644 index 0000000000..162d63b59a --- /dev/null +++ b/main/quickstart/create-project.html @@ -0,0 +1,649 @@ + + + + + + + + + + + + + Creating a project | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Creating a project

      +

      To create a new project run:

      +
      cargo new myproject
      +
      +
      +

      In Cargo.toml add useful dependencies:

      +
      [dependencies]
      +scylla = "0.13"
      +tokio = { version = "1.12", features = ["full"] }
      +futures = "0.3.6"
      +uuid = "1.0"
      +bigdecimal = "0.4"
      +num-bigint = "0.3"
      +tracing = "0.1.36"
      +tracing-subscriber = { version = "0.3.14", features = ["env-filter"] }
      +
      +
      +

      In main.rs put:

      +
      use scylla::Session;
      +
      +#[tokio::main]
      +async fn main() {
      +    println!("Hello scylla!");
      +}
      +
      +
      +

      Now running cargo run should print:

      +
      Hello scylla!
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/quickstart/example.html b/main/quickstart/example.html new file mode 100644 index 0000000000..9766bec35a --- /dev/null +++ b/main/quickstart/example.html @@ -0,0 +1,670 @@ + + + + + + + + + + + + + Connecting and running a simple query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Connecting and running a simple query

      +

      Now everything is ready to use the driver. +Here is a small example:

      +
      use scylla::{IntoTypedRows, Session, SessionBuilder};
      +use std::error::Error;
      +
      +#[tokio::main]
      +async fn main() -> Result<(), Box<dyn Error>> {
      +    // Create a new Session which connects to node at 127.0.0.1:9042
      +    // (or SCYLLA_URI if specified)
      +    let uri = std::env::var("SCYLLA_URI")
      +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
      +
      +    let session: Session = SessionBuilder::new()
      +        .known_node(uri)
      +        .build()
      +        .await?;
      +
      +    // Create an example keyspace and table
      +    session
      +        .query(
      +            "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \
      +            {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}",
      +            &[],
      +        )
      +        .await?;
      +
      +    session
      +        .query(
      +            "CREATE TABLE IF NOT EXISTS ks.extab (a int primary key)",
      +            &[],
      +        )
      +        .await?;
      +
      +    // Insert a value into the table
      +    let to_insert: i32 = 12345;
      +    session
      +        .query("INSERT INTO ks.extab (a) VALUES(?)", (to_insert,))
      +        .await?;
      +
      +    // Query rows from the table and print them
      +    let result = session.query("SELECT a FROM ks.extab", &[]).await?;
      +    let mut iter = result.rows_typed::<(i32,)>()?;
      +    while let Some(read_row) = iter.next().transpose()? {
      +        println!("Read a value from row: {}", read_row.0);
      +    }
      +
      +    Ok(())
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/quickstart/quickstart.html b/main/quickstart/quickstart.html new file mode 100644 index 0000000000..30a9a7a3b8 --- /dev/null +++ b/main/quickstart/quickstart.html @@ -0,0 +1,623 @@ + + + + + + + + + + + + + Quick Start | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Quick Start

      +

      In this chapter we will set up a Rust project and run a few simple queries.

      +

      Topics Include:

      + +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/quickstart/scylla-docker.html b/main/quickstart/scylla-docker.html new file mode 100644 index 0000000000..4ff4fc4850 --- /dev/null +++ b/main/quickstart/scylla-docker.html @@ -0,0 +1,652 @@ + + + + + + + + + + + + + Running Scylla using Docker | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Running Scylla using Docker

      +

      To make queries we will need a running Scylla instance. The easiest way is to use a Docker image.
      +Please install Docker if it’s not installed.

      +
      +

      Running scylla

      +

      To start Scylla run:

      +
      # on Linux sudo might be required
      +docker run --rm -it -p 9042:9042 scylladb/scylla --smp 2
      +
      +
      +

      Docker will download the image, then after minute or two there should be a message like:

      +
      Starting listening for CQL clients on 172.17.0.2:9042
      +
      +
      +

      This means that Scylla is ready to receive queries

      +

      To stop this instance press Ctrl + C

      +
      +
      +

      More information

      +

      More information about this image can be found on dockerhub

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/retry-policy/default.html b/main/retry-policy/default.html new file mode 100644 index 0000000000..34d3abf739 --- /dev/null +++ b/main/retry-policy/default.html @@ -0,0 +1,698 @@ + + + + + + + + + + + + + Default retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Default retry policy

      +

      This is the retry policy used by default. It retries when there is a high chance that it might help.
      +This policy is based on the one in DataStax Java Driver. +The behaviour is the same.

      +
      +

      Examples

      +

      To use in Session:

      +
      use scylla::{Session, SessionBuilder};
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::retry_policy::DefaultRetryPolicy;
      +
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .default_execution_profile_handle(handle)
      +    .build()
      +    .await?;
      +
      +
      +

      To use in a simple query:

      +
      use scylla::query::Query;
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::retry_policy::DefaultRetryPolicy;
      +
      +// Create a Query manually and set the retry policy
      +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
      +my_query.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new())));
      +
      +// You can also set retry policy in an execution profile
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +my_query.set_execution_profile_handle(Some(handle));
      +
      +// Run the query using this retry policy
      +let to_insert: i32 = 12345;
      +session.query(my_query, (to_insert,)).await?;
      +
      +
      +

      To use in a prepared query:

      +
      use scylla::prepared_statement::PreparedStatement;
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::retry_policy::DefaultRetryPolicy;
      +
      +// Create PreparedStatement manually and set the retry policy
      +let mut prepared: PreparedStatement = session
      +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
      +    .await?;
      +prepared.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new())));
      +
      +// You can also set retry policy in an execution profile
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +prepared.set_execution_profile_handle(Some(handle));
      +
      +// Run the query using this retry policy
      +let to_insert: i32 = 12345;
      +session.execute(&prepared, (to_insert,)).await?;
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/retry-policy/downgrading-consistency.html b/main/retry-policy/downgrading-consistency.html new file mode 100644 index 0000000000..e019eaf115 --- /dev/null +++ b/main/retry-policy/downgrading-consistency.html @@ -0,0 +1,739 @@ + + + + + + + + + + + + + Downgrading consistency retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Downgrading consistency retry policy

      +

      A retry policy that sometimes retries with a lower consistency level than the one initially +requested. +BEWARE: this policy may retry queries using a lower consistency level than the one +initially requested. By doing so, it may break consistency guarantees. In other words, if you use +this retry policy, there are cases (documented below) where a read at Consistency::Quorum may +not see a preceding write at Consistency::Quorum. Do not use this policy unless you have +understood the cases where this can happen and are ok with that. It is also highly recommended to +always log the occurrences of such consistency breaks. +This policy implements the same retries than the DefaultRetryPolicy policy. But on top +of that, it also retries in the following cases:

      +
        +
      • On a read timeout: if the number of replicas that responded is greater than one, but lower +than is required by the requested consistency level, the operation is retried at a lower +consistency level.

      • +
      • On a write timeout: if the operation is a WriteType::UnloggedBatch and at least one +replica acknowledged the write, the operation is retried at a lower consistency level. +Furthermore, for other operations, if at least one replica acknowledged the write, the +timeout is ignored.

      • +
      • On an unavailable exception: if at least one replica is alive, the operation is retried at +a lower consistency level.

      • +
      +

      The lower consistency level to use for retries is determined by the following rules:

      +
        +
      • if more than 3 replicas responded, use Consistency::Three.

      • +
      • if 1, 2 or 3 replicas responded, use the corresponding level Consistency::One, Consistency::Two or +Consistency::Three.

      • +
      +

      Note that if the initial consistency level was Consistency::EachQuorum, Scylla returns the number +of live replicas in the datacenter that failed to reach consistency, not the overall +number in the cluster. Therefore if this number is 0, we still retry at Consistency::One, on the +assumption that a host may still be up in another datacenter. +The reasoning being this retry policy is the following one. If, based on the information the +Scylla coordinator node returns, retrying the operation with the initially requested +consistency has a chance to succeed, do it. Otherwise, if based on this information we know +the initially requested consistency level cannot be achieved currently, then:

      +
        +
      • For writes, ignore the exception (thus silently failing the consistency requirement) if we +know the write has been persisted on at least one replica.

      • +
      • For reads, try reading at a lower consistency level (thus silently failing the consistency +requirement). +In other words, this policy implements the idea that if the requested consistency level cannot be +achieved, the next best thing for writes is to make sure the data is persisted, and that reading +something is better than reading nothing, even if there is a risk of reading stale data.

      • +
      +

      This policy is based on the one in DataStax Java Driver. +The behaviour is the same.

      +
      +

      Examples

      +

      To use in Session:

      +
      use scylla::{Session, SessionBuilder};
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
      +
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .default_execution_profile_handle(handle)
      +    .build()
      +    .await?;
      +
      +
      +

      To use in a simple query:

      +
      use scylla::query::Query;
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
      +
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +
      +// Create a Query manually and set the retry policy
      +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
      +my_query.set_execution_profile_handle(Some(handle));
      +
      +// Run the query using this retry policy
      +let to_insert: i32 = 12345;
      +session.query(my_query, (to_insert,)).await?;
      +
      +
      +

      To use in a prepared query:

      +
      use scylla::prepared_statement::PreparedStatement;
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
      +
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +
      +// Create PreparedStatement manually and set the retry policy
      +let mut prepared: PreparedStatement = session
      +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
      +    .await?;
      +
      +prepared.set_execution_profile_handle(Some(handle));
      +
      +
      +// Run the query using this retry policy
      +let to_insert: i32 = 12345;
      +session.execute(&prepared, (to_insert,)).await?;
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/retry-policy/fallthrough.html b/main/retry-policy/fallthrough.html new file mode 100644 index 0000000000..1933ecc10f --- /dev/null +++ b/main/retry-policy/fallthrough.html @@ -0,0 +1,693 @@ + + + + + + + + + + + + + Fallthrough retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Fallthrough retry policy

      +

      The FalthroughRetryPolicy never retries, returns errors straight to the user. Useful for debugging.

      +
      +

      Examples

      +

      To use in Session:

      +
      use scylla::{Session, SessionBuilder};
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::retry_policy::FallthroughRetryPolicy;
      +
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .default_execution_profile_handle(handle)
      +    .build()
      +    .await?;
      +
      +
      +

      To use in a simple query:

      +
      use scylla::query::Query;
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::retry_policy::FallthroughRetryPolicy;
      +
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +
      +// Create a Query manually and set the retry policy
      +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
      +my_query.set_execution_profile_handle(Some(handle));
      +
      +// Run the query using this retry policy
      +let to_insert: i32 = 12345;
      +session.query(my_query, (to_insert,)).await?;
      +
      +
      +

      To use in a prepared query:

      +
      use scylla::prepared_statement::PreparedStatement;
      +use scylla::transport::ExecutionProfile;
      +use scylla::transport::retry_policy::FallthroughRetryPolicy;
      +
      +let handle = ExecutionProfile::builder()
      +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
      +    .build()
      +    .into_handle();
      +
      +// Create PreparedStatement manually and set the retry policy
      +let mut prepared: PreparedStatement = session
      +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
      +    .await?;
      +
      +prepared.set_execution_profile_handle(Some(handle));
      +
      +// Run the query using this retry policy
      +let to_insert: i32 = 12345;
      +session.execute(&prepared, (to_insert,)).await?;
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/retry-policy/retry-policy.html b/main/retry-policy/retry-policy.html new file mode 100644 index 0000000000..e2d92ebb2a --- /dev/null +++ b/main/retry-policy/retry-policy.html @@ -0,0 +1,664 @@ + + + + + + + + + + + + + Retry policy configuration | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Retry policy configuration

      +

      After a query fails the driver might decide to retry it based on its Retry Policy and the query itself. +Retry policy can be configured for Session or just for a single query.

      +
      +

      Retry policies

      +

      By default there are three retry policies:

      + +

      It’s possible to implement a custom Retry Policy by implementing the traits RetryPolicy and RetrySession.

      +
      +
      +

      Query idempotence

      +

      A query is idempotent if it can be applied multiple times without changing the result of the initial application

      +

      Specifying that a query is idempotent increases the chances that it will be retried in case of failure. +Idempotent queries can be retried in situations where retrying non idempotent queries would be dangerous.

      +

      Idempotence has to be specified manually, the driver is not able to figure it out by itself.

      +
      use scylla::query::Query;
      +use scylla::prepared_statement::PreparedStatement;
      +
      +// Specify that a Query is idempotent
      +let mut my_query: Query = Query::new("SELECT a FROM ks.tab");
      +my_query.set_is_idempotent(true);
      +
      +
      +// Specify that a PreparedStatement is idempotent
      +let mut prepared: PreparedStatement = session
      +    .prepare("SELECT a FROM ks.tab")
      +    .await?;
      +
      +prepared.set_is_idempotent(true);
      +
      +
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/schema/schema.html b/main/schema/schema.html new file mode 100644 index 0000000000..8017fbc437 --- /dev/null +++ b/main/schema/schema.html @@ -0,0 +1,679 @@ + + + + + + + + + + + + + Schema | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + +
      +

      Schema

      +

      The driver is capable of fetching database schema and presenting it to its users.

      +
      +

      Fetching schema

      +

      Fetching database schema occurs periodically, but it can also be done on-demand. In order to fetch the newest database schema, one can call refresh_metadata() on a Session instance:

      +
      #[tokio::main]
      +async fn main() -> Result<(), Box<dyn Error>> {
      +    let uri = std::env::var("SCYLLA_URI")
      +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
      +
      +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
      +    // Schema metadata will be fetched below
      +    session.refresh_metadata().await?;
      +    Ok(())
      +}
      +
      +
      +
      +
      +

      Inspecting schema

      +

      Once fetched, a snapshot of cluster’s schema can be examined. The following information can be obtained:

      +
        +
      • keyspace

        +
          +
        • tables belonging to the keyspace

        • +
        • materialized views belonging to the keyspace

        • +
        • replication strategy

        • +
        • user-defined types

        • +
        +
      • +
      • table/view

        +
          +
        • primary key definition

        • +
        • columns

        • +
        • partitioner type

        • +
        +
      • +
      +

      Example showing how to print obtained schema information:

      +
      #[tokio::main]
      +async fn main() -> Result<(), Box<dyn Error>> {
      +    let uri = std::env::var("SCYLLA_URI")
      +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
      +
      +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
      +    // Schema metadata will be fetched below
      +    session.refresh_metadata().await?;
      +
      +    let cluster_data = &session.get_cluster_data();
      +    let keyspaces = &cluster_data.get_keyspace_info();
      +
      +    for (keyspace_name, keyspace_info) in keyspaces.iter() {
      +        println!("Keyspace {}:", keyspace_name);
      +        println!("\tTables: {:#?}", keyspace_info.tables);
      +        println!("\tViews: {:#?}", keyspace_info.views);
      +        println!("\tUDTs: {:#?}", keyspace_info.user_defined_types);
      +    }
      +
      +    Ok(())
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/search.html b/main/search.html new file mode 100644 index 0000000000..714fe0ed3e --- /dev/null +++ b/main/search.html @@ -0,0 +1,598 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + + + + + +
      + + + + + +
      + + +
      + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/searchindex.js b/main/searchindex.js new file mode 100644 index 0000000000..1ae1ca4ff1 --- /dev/null +++ b/main/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["connecting/authentication", "connecting/compression", "connecting/connecting", "connecting/tls", "contents", "data-types/blob", "data-types/collections", "data-types/counter", "data-types/data-types", "data-types/date", "data-types/decimal", "data-types/duration", "data-types/inet", "data-types/primitive", "data-types/text", "data-types/time", "data-types/timestamp", "data-types/timeuuid", "data-types/tuple", "data-types/udt", "data-types/uuid", "data-types/varint", "execution-profiles/create-and-use", "execution-profiles/execution-profiles", "execution-profiles/maximal-example", "execution-profiles/priority", "execution-profiles/remap", "index", "load-balancing/default-policy", "load-balancing/load-balancing", "logging/logging", "metrics/metrics", "migration-guides/0.11-serialization", "migration-guides/migration-guides", "queries/batch", "queries/lwt", "queries/paged", "queries/prepared", "queries/queries", "queries/result", "queries/schema-agreement", "queries/simple", "queries/timeouts", "queries/usekeyspace", "queries/values", "quickstart/create-project", "quickstart/example", "quickstart/quickstart", "quickstart/scylla-docker", "retry-policy/default", "retry-policy/downgrading-consistency", "retry-policy/fallthrough", "retry-policy/retry-policy", "schema/schema", "speculative-execution/percentile", "speculative-execution/simple", "speculative-execution/speculative", "tracing/basic", "tracing/paged", "tracing/prepare", "tracing/query-history", "tracing/tracing"], "filenames": ["connecting/authentication.md", "connecting/compression.md", "connecting/connecting.md", "connecting/tls.md", "contents.rst", "data-types/blob.md", "data-types/collections.md", "data-types/counter.md", "data-types/data-types.md", "data-types/date.md", "data-types/decimal.md", "data-types/duration.md", "data-types/inet.md", "data-types/primitive.md", "data-types/text.md", "data-types/time.md", "data-types/timestamp.md", "data-types/timeuuid.md", "data-types/tuple.md", "data-types/udt.md", "data-types/uuid.md", "data-types/varint.md", "execution-profiles/create-and-use.md", "execution-profiles/execution-profiles.md", "execution-profiles/maximal-example.md", "execution-profiles/priority.md", "execution-profiles/remap.md", "index.md", "load-balancing/default-policy.md", "load-balancing/load-balancing.md", "logging/logging.md", "metrics/metrics.md", "migration-guides/0.11-serialization.md", "migration-guides/migration-guides.md", "queries/batch.md", "queries/lwt.md", "queries/paged.md", "queries/prepared.md", "queries/queries.md", "queries/result.md", "queries/schema-agreement.md", "queries/simple.md", "queries/timeouts.md", "queries/usekeyspace.md", "queries/values.md", "quickstart/create-project.md", "quickstart/example.md", "quickstart/quickstart.md", "quickstart/scylla-docker.md", "retry-policy/default.md", "retry-policy/downgrading-consistency.md", "retry-policy/fallthrough.md", "retry-policy/retry-policy.md", "schema/schema.md", "speculative-execution/percentile.md", "speculative-execution/simple.md", "speculative-execution/speculative.md", "tracing/basic.md", "tracing/paged.md", "tracing/prepare.md", "tracing/query-history.md", "tracing/tracing.md"], "titles": ["Authentication", "Compression", "Connecting to the cluster", "TLS", "<no title>", "Blob", "List, Set, Map", "Counter", "Data Types", "Date", "Decimal", "Duration", "Inet", "Bool, Tinyint, Smallint, Int, Bigint, Float, Double", "Ascii, Text, Varchar", "Time", "Timestamp", "Timeuuid", "Tuple", "User defined types", "Uuid", "Varint", "Creating a profile and setting it", "Execution profiles", "All options supported by a profile", "Priorities of execution settings", "Remapping execution profile handles", "Scylla Rust Driver", "DefaultPolicy", "Load balancing", "Logging", "Driver metrics", "Adjusting code to changes in serialization API introduced in 0.11", "Migration guides", "Batch statement", "Lightweight transaction (LWT) query", "Paged query", "Prepared query", "Making queries", "Query result", "Schema agreement", "Simple query", "Query timeouts", "USE keyspace", "Query values", "Creating a project", "Connecting and running a simple query", "Quick Start", "Running Scylla using Docker", "Default retry policy", "Downgrading consistency retry policy", "Fallthrough retry policy", "Retry policy configuration", "Schema", "Percentile speculative execution", "Simple speculative execution", "Speculative execution", "Tracing a simple/prepared/batch query", "Tracing a paged query", "Tracing Session::prepare", "Query Execution History", "Query tracing"], "terms": {"driver": [0, 1, 2, 3, 8, 19, 28, 29, 30, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 49, 50, 52, 53, 56, 61], "support": [0, 1, 2, 3, 9, 15, 16, 21, 28, 32, 38, 42, 61], "both": [0, 32], "usernam": [0, 2], "password": [0, 2], "defin": [0, 8, 26, 32, 35, 40, 53], "user": [0, 8, 10, 21, 28, 32, 37, 51, 52, 53], "To": [0, 3, 10, 17, 19, 21, 22, 28, 29, 30, 32, 37, 39, 41, 45, 48, 49, 50, 51, 54, 55, 60], "specifi": [0, 1, 2, 25, 28, 34, 37, 41, 44, 46, 52, 60], "method": [0, 2, 28, 29, 32, 43, 56], "sessionbuild": [0, 1, 2, 3, 22, 25, 26, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "scylla": [0, 1, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 32, 34, 35, 36, 37, 38, 39, 41, 42, 44, 45, 46, 47, 49, 50, 51, 52, 54, 55, 57, 58, 59, 60, 61], "session": [0, 1, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 29, 30, 31, 32, 34, 35, 36, 39, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61], "let": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 30, 31, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "new": [0, 1, 2, 3, 6, 12, 16, 22, 24, 25, 26, 28, 29, 30, 34, 35, 36, 40, 41, 42, 44, 45, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "known_nod": [0, 1, 2, 3, 22, 25, 26, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "127": [0, 1, 2, 3, 12, 22, 25, 26, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55, 60], "0": [0, 1, 2, 3, 7, 10, 12, 13, 16, 18, 22, 25, 26, 30, 33, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 53, 54, 55, 60], "1": [0, 1, 2, 3, 5, 6, 9, 11, 12, 15, 16, 18, 22, 25, 26, 28, 30, 32, 34, 36, 37, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 53, 54, 55, 60], "9042": [0, 1, 2, 22, 25, 26, 30, 40, 42, 46, 48, 49, 50, 51, 53, 54, 55, 60], "myusernam": 0, "mypassword": 0, "build": [0, 1, 2, 3, 17, 22, 24, 25, 26, 28, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "await": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 29, 30, 34, 35, 36, 37, 39, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "A": [0, 32, 34, 35, 44, 50, 52, 58, 60], "implement": [0, 28, 29, 34, 41, 44, 50, 52, 60], "authenticatorsess": 0, "an": [0, 1, 2, 3, 9, 13, 15, 16, 22, 23, 25, 27, 28, 29, 35, 36, 39, 40, 41, 44, 46, 49, 50, 56, 60], "instanc": [0, 2, 23, 28, 29, 40, 48, 53], "creat": [0, 2, 3, 19, 23, 29, 30, 34, 35, 37, 40, 41, 43, 46, 47, 49, 50, 51, 57, 58, 60], "per": [0, 2, 29, 37, 42], "so": [0, 2, 3, 25, 26, 28, 29, 32, 35, 40, 42, 50], "also": [0, 2, 16, 17, 19, 25, 26, 27, 28, 29, 32, 43, 44, 49, 50, 52, 53], "necessari": [0, 40], "authenticatorprovid": 0, "final": [0, 32, 60], "make": [0, 10, 21, 27, 29, 32, 35, 40, 44, 48, 50], "authenticator_provid": 0, "byte": 0, "bufmut": [0, 32], "bytesmut": 0, "async_trait": 0, "autherror": 0, "struct": [0, 7, 8, 19, 32, 37, 44, 60], "customauthent": 0, "impl": [0, 32], "handl": [0, 2, 19, 22, 23, 29, 39, 41, 49, 50, 51, 54, 55], "challeng": 0, "initi": [0, 29, 50, 52], "inform": [0, 2, 8, 16, 19, 29, 32, 34, 36, 41, 44, 50, 53, 60, 61], "contain": [0, 2, 27, 29, 34, 35, 39, 57, 58, 59, 61], "token": [0, 29, 34, 37, 41], "paramet": [0, 19, 35, 60], "protocol": [0, 32], "specif": [0, 25, 28, 29, 35, 61], "It": [0, 1, 3, 9, 15, 16, 28, 29, 32, 35, 36, 39, 42, 43, 49, 50, 52, 55, 61], "mai": [0, 28, 32, 42, 50], "null": [0, 19], "empti": [0, 34, 36, 37, 41, 44], "async": [0, 1, 2, 30, 36, 45, 46, 53], "fn": [0, 1, 2, 30, 32, 45, 46, 53], "evaluate_challeng": 0, "mut": [0, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 32, 34, 35, 36, 37, 41, 42, 44, 46, 49, 50, 51, 52, 57, 58, 59, 60], "self": [0, 2, 32], "_token": 0, "option": [0, 19, 23, 25, 27, 29, 32, 35, 39, 41, 44, 57], "u8": [0, 5, 8], "result": [0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 30, 32, 34, 36, 37, 38, 42, 44, 46, 52, 53, 59, 60], "vec": [0, 5, 6, 8, 10, 39, 41], "err": [0, 40], "expect": [0, 16, 32], "to_str": [0, 1, 2, 6, 14, 18, 19, 28, 30, 35, 42, 44, 46, 53], "success": [0, 29, 37, 52, 60], "phase": 0, "exchang": 0, "request": [0, 2, 22, 23, 25, 28, 29, 31, 32, 34, 36, 37, 41, 42, 44, 50, 54, 59, 60], "ok": [0, 1, 2, 30, 40, 46, 50, 53], "customauthenticatorprovid": 0, "start_authentication_sess": 0, "_name": 0, "str": [0, 8, 10, 14, 21, 32, 44], "box": [0, 1, 2, 24, 30, 46, 49, 50, 51, 53], "dyn": [0, 1, 2, 30, 46, 53], "respons": [0, 28, 32, 38, 39, 42, 60], "cred": 0, "0cassandra": 0, "cred_length": 0, "20": 0, "put_i32": 0, "put_slic": 0, "as_byt": 0, "some": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 35, 36, 37, 39, 40, 41, 42, 44, 46, 49, 50, 51, 52, 54, 55, 57, 58, 60, 61], "to_vec": 0, "authentication_exampl": 0, "error": [0, 1, 2, 15, 29, 30, 31, 37, 39, 42, 46, 51, 52, 53, 60], "_session": 0, "arc": [0, 2, 24, 29, 49, 54, 55, 60], "By": [1, 2, 28, 32, 34, 37, 41, 44, 50, 52], "default": [1, 2, 19, 22, 24, 25, 28, 29, 30, 34, 35, 37, 40, 41, 42, 44, 52, 56, 57], "doe": [1, 32, 41, 42, 55, 60, 61], "us": [1, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 40, 41, 42, 44, 45, 46, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61], "ani": [1, 2, 9, 10, 15, 16, 19, 21, 23, 25, 31, 32, 35, 36, 37, 60, 61], "connect": [1, 27, 29, 30, 43, 59], "": [1, 2, 3, 9, 15, 16, 19, 25, 26, 28, 29, 32, 34, 35, 36, 37, 39, 41, 43, 44, 48, 52, 53, 60, 61], "possibl": [1, 28, 29, 32, 34, 36, 39, 42, 43, 52, 60, 61], "prefer": [1, 25, 36, 37, 43], "algorithm": 1, "The": [1, 2, 3, 8, 17, 19, 23, 28, 29, 30, 32, 35, 37, 39, 40, 41, 42, 43, 48, 49, 50, 51, 53, 55, 60, 61], "try": [1, 2, 28, 29, 50, 60], "databas": [1, 2, 3, 8, 15, 16, 19, 27, 29, 32, 41, 44, 53, 61], "doesn": [1, 2, 3, 16, 37, 38, 60, 61], "t": [1, 2, 3, 6, 7, 8, 15, 16, 32, 36, 37, 38, 39, 40, 41, 43, 60, 61], "fall": [1, 28, 42], "back": [1, 42], "avail": [1, 9, 15, 16, 21, 25, 28, 30, 38, 55, 56, 61], "snappi": 1, "lz4": 1, "exampl": [1, 2, 3, 8, 19, 27, 29, 30, 32, 34, 37, 41, 43, 44, 46, 47, 53], "enabl": [1, 9, 10, 15, 16, 17, 21, 26, 28, 29, 38, 56, 57, 58, 59, 60], "transport": [1, 22, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55, 58], "std": [1, 2, 3, 6, 8, 10, 12, 21, 22, 24, 28, 29, 30, 42, 46, 53, 54, 55, 60], "tokio": [1, 2, 30, 45, 46, 53], "main": [1, 2, 30, 45, 46, 53], "uri": [1, 2, 29, 30, 42, 46, 53], "env": [1, 2, 30, 42, 45, 46, 53], "var": [1, 2, 30, 42, 46, 53], "scylla_uri": [1, 2, 30, 42, 46, 53], "unwrap_or_els": [1, 2, 30, 42, 46, 53], "_": [1, 2, 30, 32, 36, 42, 46, 53], "i": [2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 23, 25, 27, 28, 29, 30, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 48, 49, 50, 52, 53, 54, 56, 58, 59, 60, 61], "distribut": [2, 28], "which": [2, 3, 10, 17, 21, 23, 25, 28, 29, 30, 32, 34, 36, 37, 39, 40, 41, 44, 46, 57, 60, 61], "mean": [2, 28, 29, 32, 36, 44, 48], "oper": [2, 28, 31, 34, 42, 44, 50, 61], "multipl": [2, 38, 52, 56, 58], "node": [2, 29, 34, 36, 37, 40, 41, 42, 46, 50, 56, 60, 61], "run": [2, 23, 27, 30, 34, 37, 38, 43, 45, 47, 49, 50, 51, 60], "independ": 2, "when": [2, 19, 27, 28, 29, 32, 35, 37, 38, 39, 41, 42, 43, 44, 49, 54, 60, 61], "you": [2, 3, 17, 19, 25, 26, 28, 29, 30, 32, 34, 37, 38, 40, 41, 44, 49, 50, 61], "can": [2, 5, 7, 9, 10, 15, 16, 17, 19, 21, 23, 25, 26, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 48, 49, 50, 52, 53, 56, 60, 61], "few": [2, 27, 39, 44, 47], "known": 2, "time": [2, 8, 22, 24, 28, 32, 40, 41, 42, 52, 54, 55, 60], "durat": [2, 8, 22, 24, 28, 40, 42, 54, 55], "net": [2, 8, 12], "ipaddr": [2, 8, 12], "ipv4addr": [2, 12], "socketaddr": 2, "72": 2, "4321": 2, "localhost": 2, "8000": 2, "connection_timeout": 2, "from_sec": [2, 22, 24, 28, 40, 42], "3": [2, 5, 6, 8, 9, 10, 11, 15, 21, 24, 28, 32, 34, 42, 44, 45, 50, 54, 55], "cluster_metadata_refresh_interv": 2, "10": [2, 3], "known_node_addr": 2, "v4": [2, 12], "9000": 2, "after": [2, 19, 28, 32, 40, 48, 52, 55, 61], "successfulli": [2, 29], "fetch": [2, 27, 36, 41, 58, 61], "topologi": 2, "about": [2, 8, 17, 27, 29, 32, 34, 41, 44, 48, 60, 61], "other": [2, 9, 15, 16, 19, 28, 29, 32, 35, 37, 43, 50, 60], "thi": [2, 19, 23, 26, 27, 28, 29, 30, 32, 34, 36, 37, 38, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 60, 61], "them": [2, 25, 27, 28, 32, 34, 37, 38, 39, 41, 44, 46, 60], "well": [2, 28], "alwai": [2, 25, 35, 37, 50], "onli": [2, 7, 9, 15, 16, 28, 29, 32, 34, 35, 37, 40, 41, 56], "singl": [2, 23, 32, 36, 38, 39, 41, 44, 52, 60], "object": [2, 17, 23, 34], "apllic": 2, "becaus": [2, 3, 29, 36, 41], "veri": [2, 10, 21, 28, 32], "expens": 2, "maintain": 2, "its": [2, 9, 23, 28, 29, 32, 34, 52, 53, 56, 60], "own": [2, 19, 29], "pool": 2, "each": [2, 8, 28, 29, 32, 34, 36, 41, 44, 58, 59, 60], "capabl": [2, 53], "parallel": [2, 38, 60], "rout": [2, 28], "shard": [2, 29, 34, 37, 41], "actual": [2, 32, 42], "data": [2, 19, 27, 28, 29, 32, 34, 37, 41, 50], "unless": [2, 28, 32, 50], "load": [2, 23, 27, 28, 34, 37, 38, 41], "balanc": [2, 23, 27, 28, 34, 37, 38, 41], "polici": [2, 23, 27, 28, 54, 55, 60], "For": [2, 3, 19, 29, 32, 34, 35, 36, 37, 39, 40, 41, 43, 50], "those": [2, 25, 28, 32], "reason": [2, 32, 37, 50], "we": [2, 5, 26, 32, 37, 40, 43, 44, 47, 48, 50, 60, 61], "recommend": [2, 28, 29, 32, 50], "one": [2, 19, 21, 25, 32, 34, 36, 37, 39, 42, 43, 49, 50, 53, 55, 60], "applic": [2, 28, 40, 42, 52], "short": 2, "live": [2, 50], "e": [2, 9, 28, 29, 32, 35, 40, 42], "g": [2, 28, 29, 32, 35, 40], "strongli": [2, 34], "discourag": [2, 34], "great": 2, "perform": [2, 28, 29, 32, 38, 40, 44, 58, 60, 61], "penalti": [2, 36], "costli": 2, "process": [2, 42], "requir": [2, 9, 16, 19, 32, 35, 36, 41, 44, 48, 50], "estabilish": 2, "lot": [2, 40], "tcp": 2, "mani": [2, 34, 38, 60], "thread": 2, "task": 2, "wast": 2, "resourc": 2, "mention": [2, 32], "befor": [2, 9, 28, 32, 34, 37, 38, 40, 56], "itself": [2, 32, 35, 39, 52], "queri": [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 40, 47, 48, 49, 50, 51, 55, 56, 59], "would": [2, 32, 52, 60, 61], "hold": 2, "unnecessarili": 2, "If": [2, 9, 15, 16, 28, 32, 36, 37, 40, 41, 42, 43, 44, 50, 58, 59, 61], "need": [2, 3, 17, 29, 36, 37, 38, 39, 40, 41, 43, 48, 61], "share": [2, 23, 54], "differ": [2, 9, 15, 16, 19, 23, 27, 35, 43, 44], "etc": [2, 27, 60, 61], "all": [2, 16, 22, 23, 26, 27, 28, 30, 32, 34, 37, 38, 40, 41, 52, 58, 59, 60, 61], "take": [2, 32, 34, 36, 37, 41], "hinder": 2, "function": [2, 3, 38, 40], "wai": [2, 23, 26, 36, 37, 39, 41, 48, 61], "refresh": 2, "period": [2, 53], "schema": [2, 27, 32], "everi": [2, 28, 40], "60": 2, "second": [2, 15, 16, 32, 34, 42, 43, 56], "howev": [2, 9, 15, 16, 32, 37, 40, 42, 60], "set": [2, 8, 23, 27, 28, 29, 32, 34, 35, 37, 41, 42, 43, 47, 49, 50, 51, 61], "non": [2, 28, 34, 35, 36, 37, 52, 55, 56, 60], "neg": [2, 15], "valu": [2, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 28, 35, 36, 37, 40, 43, 46, 49, 50, 51, 57, 58, 61], "do": [2, 27, 29, 32, 34, 40, 50, 60], "have": [2, 3, 19, 25, 26, 29, 30, 32, 34, 35, 36, 37, 39, 40, 42, 44, 50], "unexpect": 2, "amount": [2, 37, 41, 60], "traffic": [2, 28], "extra": [2, 9, 15, 16], "caus": [2, 29, 37, 41], "chang": [2, 19, 23, 26, 33, 34, 35, 37, 40, 41, 44, 52, 60], "frequent": 2, "elast": 2, "dynam": 2, "deploy": 2, "model": 2, "secur": 2, "bundl": 2, "follow": [2, 8, 9, 15, 16, 17, 23, 24, 25, 26, 28, 32, 50, 53, 61], "path": [2, 3], "cloudsessionbuild": 2, "config_data": 2, "yaml": 2, "unwrap": [2, 9, 15, 16, 31, 39], "note": [2, 19, 28, 32, 34, 37, 42, 50], "file": [2, 3], "provid": [2, 29, 32, 37, 39, 42, 44, 60, 61], "here": [2, 17, 28, 39, 41, 46, 60], "configur": [2, 23, 27, 28, 30, 32, 56], "datacent": [2, 35, 50], "datacenter1": 2, "certificateauthoritydata": 2, "certificate_data": 2, "server": [2, 37, 42], "9142": [2, 3], "nodedomain": 2, "cql": [2, 8, 19, 32, 35, 43, 48], "id": [2, 57, 58, 59, 61], "com": 2, "insecureskiptlsverifi": 2, "fals": [2, 28, 40, 43], "authinfo": 2, "clientcertificatedata": 2, "clientkeydata": 2, "key_data": 2, "scylladb": [2, 42, 48], "context": 2, "datacenternam": 2, "authinfonam": 2, "currentcontext": 2, "openssl": 3, "crate": [3, 10, 17, 30, 32, 60], "wa": [3, 19, 29, 37, 39, 50, 57, 61], "chosen": 3, "rustl": 3, "certif": 3, "ip": [3, 12], "address": [3, 12, 17, 28], "see": [3, 8, 9, 15, 16, 19, 26, 29, 32, 34, 35, 37, 39, 41, 43, 44, 50, 60], "issu": [3, 32, 36, 44], "common": [3, 23, 29], "case": [3, 9, 15, 16, 25, 28, 29, 32, 36, 37, 40, 41, 50, 52, 60], "pure": 3, "rust": [3, 8, 13, 18, 19, 28, 32, 35, 37, 39, 41, 44, 47], "librari": 3, "instal": [3, 30, 47, 48], "proper": 3, "packag": 3, "add": [3, 17, 34, 45], "cargo": [3, 17, 30, 45], "toml": [3, 45], "version": [3, 27, 32, 33, 40, 45], "4": [3, 5, 6, 8, 16, 21, 32, 34, 45, 57, 58], "ssl": 3, "32": [3, 10], "Then": 3, "debian": 3, "ubuntu": 3, "apt": 3, "libssl": 3, "dev": 3, "pkg": 3, "config": 3, "fedora": 3, "dnf": 3, "devel": 3, "arch": 3, "pacman": 3, "sslcontext": 3, "pass": [3, 29, 34, 37, 41, 44, 60], "ca": 3, "crt": 3, "sslcontextbuild": 3, "sslmethod": 3, "sslverifymod": 3, "pathbuf": 3, "context_build": 3, "set_ca_fil": 3, "set_verifi": 3, "peer": 3, "port": 3, "now": [3, 17, 19, 26, 32, 43, 45, 46, 58, 59], "ssl_context": 3, "full": [3, 9, 16, 30, 45], "more": [3, 8, 9, 15, 16, 17, 19, 32, 34, 35, 36, 37, 39, 40, 41, 42, 44, 50, 52, 60, 61], "detail": [3, 29], "repres": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 32, 39, 41, 60], "intotypedrow": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 36, 39, 41, 46], "insert": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 34, 35, 37, 39, 41, 43, 44, 46, 49, 50, 51, 57, 58], "tabl": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 32, 35, 36, 37, 40, 41, 42, 43, 46, 53, 61], "refer": [5, 28, 29, 32, 44], "move": 5, "whole": [5, 34, 36, 56], "to_insert": [5, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 35, 37, 41, 46, 49, 50, 51], "2": [5, 6, 9, 11, 15, 32, 34, 36, 37, 41, 44, 48, 50], "5": [5, 6, 32, 34], "INTO": [5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 34, 35, 37, 39, 41, 43, 44, 46, 49, 50, 51, 57, 58], "keyspac": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 30, 38, 40, 41, 42, 46, 53], "read": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 38, 41, 46, 50, 60], "from": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 29, 30, 36, 37, 39, 41, 43, 44, 46, 52, 57, 58, 59, 60, 61], "select": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 32, 36, 39, 41, 43, 46, 52, 57, 58, 59, 60], "iter": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 29, 31, 36, 39, 41, 46, 53, 56, 58], "rows_typ": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 39, 41, 46], "while": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 32, 36, 41, 46, 58], "blob_valu": 5, "next": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 36, 41, 46, 50, 58, 60], "transpos": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 41, 46], "println": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 31, 36, 40, 41, 45, 46, 53, 57, 58, 59, 60], "int": [6, 8, 18, 19, 32, 37, 39, 44, 46], "my_list": 6, "i32": [6, 8, 13, 18, 19, 32, 35, 36, 37, 39, 41, 44, 46, 49, 50, 51], "list_valu": 6, "hashset": 6, "btreeset": 6, "my_set": 6, "collect": [6, 8], "into_it": 6, "hashmap": [6, 8, 44], "k": [6, 8, 19, 22, 24, 25, 26, 30, 34, 35, 36, 37, 39, 41, 44, 46, 49, 50, 51, 52, 57, 58, 59, 60], "v": [6, 8], "btreemap": 6, "text": [6, 8, 19, 34, 37, 39, 41, 44], "my_map": 6, "string": [6, 8, 14, 18, 19, 32, 35, 37, 39, 41, 44], "abcd": 6, "16": [6, 18, 34, 36, 37, 44], "map_valu": 6, "pub": [7, 32], "i64": [7, 8, 13, 15, 16], "updat": [7, 27, 29, 34, 40], "frame": [7, 9, 10, 11, 15, 16, 17, 39, 44], "c": [7, 36, 37, 41, 44, 48], "counter_valu": 7, "counter_int_valu": 7, "map": [8, 26, 44], "match": [8, 9, 15, 16, 19, 32, 39, 41, 44], "achiev": [8, 43, 50], "seamless": 8, "send": [8, 29, 32, 34, 36, 37, 41, 43, 44, 60, 61], "receiv": [8, 19, 30, 32, 36, 37, 39, 41, 48, 58], "chapter": [8, 29, 47, 61], "how": [8, 27, 36, 53, 61], "equival": [8, 32], "boolean": 8, "bool": 8, "tinyint": 8, "i8": [8, 13], "smallint": 8, "i16": [8, 13, 32], "bigint": [8, 45], "float": 8, "f32": [8, 13], "doubl": 8, "f64": [8, 13], "ascii": 8, "varchar": 8, "counter": 8, "blob": 8, "inet": 8, "uuid": [8, 17, 45, 57, 58, 59], "timeuuid": 8, "cqltimeuuid": [8, 17], "date": [8, 16], "cqldate": 8, "chrono": 8, "naived": [8, 16], "cqltime": 8, "naivetim": [8, 16], "timestamp": [8, 17, 60], "cqltimestamp": 8, "datetim": 8, "utc": [8, 16, 60], "offsetdatetim": 8, "cqldurat": [8, 11], "decim": 8, "cqldecim": 8, "bigdecim": [8, 45], "varint": 8, "cqlvarint": 8, "num_bigint": 8, "v0": [8, 21], "list": [8, 29, 34, 37, 41, 44, 58, 59, 60], "tupl": [8, 34, 39, 41, 44], "udt": [8, 19, 32], "custom": [8, 17, 19, 29, 37, 41, 42, 44, 52], "macro": [8, 19, 39, 44], "depend": [9, 15, 16, 36, 45], "featur": [9, 10, 15, 16, 17, 21, 45, 61], "flag": [9, 10, 15, 16, 21, 28, 61], "three": [9, 15, 16, 25, 28, 32, 44, 50, 52], "type": [9, 10, 15, 16, 17, 21, 27, 32, 35, 37, 38, 41, 53], "interact": [9, 10, 15, 16, 21], "intern": [9, 15, 16, 29], "number": [9, 10, 15, 16, 17, 21, 27, 31, 32, 34, 39, 50], "dai": [9, 11], "sinc": [9, 15, 16], "5877641": 9, "06": 9, "23": [9, 15], "31": 9, "unix": [9, 16], "epoch": [9, 16], "without": [9, 10, 15, 16, 19, 21, 32, 39, 40, 43, 52, 60], "u32": 9, "wrapper": [9, 10, 15, 16, 17, 21, 32], "represent": [9, 15, 16, 32, 60], "most": [9, 15, 16, 29, 55], "ar": [9, 14, 15, 16, 19, 23, 25, 26, 28, 29, 32, 34, 36, 37, 38, 39, 41, 43, 44, 50, 52, 56, 58, 59, 61], "practic": [9, 15, 16, 32], "section": [9, 15, 16, 32, 37], "1970": [9, 16], "01": [9, 15, 16], "08": [9, 60], "7": [9, 36], "raw": [9, 32, 43], "row": [9, 10, 15, 16, 17, 36, 41, 43, 46, 58], "into_typ": [9, 10, 15, 16, 36], "date_valu": 9, "rang": [9, 16, 28], "262145": 9, "262143": 9, "12": [9, 45], "2021": 9, "03": [9, 15, 21], "24": 9, "from_ymd_opt": [9, 16], "altern": [9, 16], "document": [9, 19, 34, 35, 37, 41, 44, 50], "get": [9, 39, 60, 61], "info": [9, 16, 30, 57, 58, 59], "month": [9, 11, 16], "from_calendar_d": [9, 16], "march": 9, "simpl": [10, 21, 27, 32, 34, 36, 37, 38, 47, 49, 50, 51, 56, 58], "sign": [10, 21], "binari": [10, 21], "big": [10, 21, 36], "endian": [10, 21], "order": [10, 17, 19, 21, 32, 36, 41, 44, 53, 60], "bit": [10, 39], "scale": 10, "fromstr": [10, 21], "123": [10, 13, 16], "456": [10, 15], "from_signed_be_bytes_and_expon": 10, "0x01": 10, "0xe2": 10, "0x40": 10, "decimal_valu": 10, "should": [10, 21, 30, 32, 41, 44, 45, 48], "04": [10, 16, 21], "from_str": [10, 17, 21], "12345": [10, 13, 21, 35, 37, 41, 43, 46, 49, 50, 51], "nanosecond": [11, 15], "duration_valu": 11, "inet_valu": 12, "true": [13, 28, 43, 52, 57, 58, 59], "bool_valu": 13, "tinyint_valu": 13, "smallint_valu": 13, "int_valu": [13, 18, 39], "bigint_valu": 13, "float_valu": 13, "double_valu": 13, "to_insert_str": 14, "abcdef": 14, "text_valu": [14, 39], "midnight": 15, "exce": 15, "86399999999999": 15, "59": 15, "999999999": 15, "64": [15, 16], "1_000_000_000": 15, "time_valu": 15, "although": [15, 27], "leap": 15, "thei": [15, 19, 21, 28, 29, 31, 32, 34, 37, 41, 44], "attempt": [15, 60, 61], "convert": [15, 16, 29, 39, 60], "write": [15, 16, 19, 28, 43, 50], "return": [15, 16, 28, 29, 32, 36, 37, 39, 40, 41, 42, 50, 51, 52, 57], "02": 15, "789": 15, "012": 15, "from_hms_nano_opt": 15, "456_789_012": 15, "from_hms_nano": 15, "describ": [16, 26, 32], "millisecond": [16, 40], "accept": 16, "00": 16, "1000": 16, "timestamp_valu": 16, "timezon": 16, "explicitli": 16, "store": [16, 28], "precis": 16, "finer": 16, "than": [16, 28, 37, 39, 40, 42, 43, 44, 50], "1m": 16, "lost": 16, "naivedatetim": 16, "from_hms_milli_opt": 16, "and_utc": 16, "As": [16, 26, 28, 32, 41, 42], "correct": [16, 28, 32], "eras": 16, "On": [16, 29, 36, 37, 50], "primitivedatetim": 16, "januari": 16, "from_hms_milli": 16, "assume_utc": 16, "logic": [17, 42], "cassandra": [17, 27, 29, 42, 61], "semant": 17, "8e14e760": [17, 20], "7fa8": [17, 20], "11eb": [17, 20], "bc66": [17, 20], "000000000001": [17, 20], "base": [17, 22, 28, 29, 30, 32, 49, 50, 52], "v1": 17, "f": 17, "re": [17, 57], "gonna": 17, "abl": [17, 19, 28, 29, 52, 60], "tip": 17, "random": [17, 28, 34, 41], "stabl": 17, "mac": 17, "node_id": 17, "0x12": 17, "0x34": 17, "0x56": 17, "0x78": 17, "0x9a": 17, "0xbc": 17, "current": [17, 37, 42, 50, 54, 56], "now_v1": 17, "learn": [17, 32], "max": [18, 44], "element": [18, 29, 44], "abc": 18, "tuple_valu": 18, "string_valu": 18, "allow": [19, 23, 28, 29, 32, 34, 36, 38, 43, 60, 61], "name": [19, 32, 39, 43, 44], "field": [19, 28, 32, 39, 44], "offici": 19, "correspond": [19, 50], "sai": [19, 37, 61], "my_typ": 19, "int_val": 19, "text_val": 19, "deriv": [19, 32, 39, 44], "serializecql": 19, "same": [19, 28, 29, 32, 35, 36, 37, 39, 43, 44, 49, 50, 60, 61], "renam": 19, "attribut": [19, 32, 44], "fromusertyp": [19, 32], "mismatch": 19, "between": [19, 23, 34], "temporari": 19, "situat": [19, 52], "futur": [19, 29, 32, 36, 40, 45, 58], "replac": [19, 32], "earlier": 19, "must": [19, 28, 32, 34, 37, 39, 44], "wrap": [19, 32, 43], "gracefulli": 19, "debug": [19, 51], "mytyp": 19, "import": [19, 35], "deseri": [19, 32, 37], "de": 19, "serial": [19, 23, 24, 33, 35, 36, 37, 41], "anoth": [19, 22, 23, 26, 32, 50, 55, 56, 60], "look": [19, 32], "behaviour": [19, 40, 49, 50], "sent": [19, 29, 32, 34, 37, 41, 44, 60, 61], "just": [19, 30, 32, 34, 35, 36, 37, 43, 44, 52, 60], "like": [19, 34, 35, 36, 37, 48, 60, 61], "cql_to_rust": [19, 39], "fromcqlval": 19, "17": [19, 44, 48], "my_type_valu": 19, "parse_str": 20, "uuid_valu": 20, "num": [21, 45], "accordingli": 21, "varint_valu": 21, "executionprofil": [22, 23, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55], "attach": 22, "statement": [22, 23, 24, 25, 26, 28, 32, 35, 37, 38, 41, 42, 57], "consist": [22, 23, 24, 25, 26, 28, 34, 35, 37, 41, 52, 60], "builder": [22, 24, 25, 26, 28, 29, 42, 49, 50, 51, 54, 55], "localon": 22, "request_timeout": [22, 24, 42], "none": [22, 28, 29, 42, 44], "timeout": [22, 23, 25, 40, 50], "into_handl": [22, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55], "default_execution_profile_handl": [22, 25, 26, 29, 42, 49, 50, 51, 54, 55], "30": [22, 24, 28, 42], "query1": [22, 26], "set_execution_profile_handl": [22, 24, 25, 26, 42, 49, 50, 51], "clone": [22, 25, 26, 36, 60], "query2": [22, 26], "pk": [22, 26, 32], "where": [22, 26, 32, 36, 40, 41, 50, 52, 56], "base_profil": 22, "to_build": 22, "group": [23, 27, 28], "variou": [23, 27, 31, 34], "togeth": [23, 27], "workload": [23, 26, 28], "conveni": [23, 26, 35], "encapsul": 23, "retri": [23, 27, 31, 40, 60, 61], "specul": [23, 29, 61], "There": [23, 28, 56, 61], "two": [23, 25, 26, 29, 32, 34, 35, 39, 43, 48, 50, 61], "class": [23, 30, 46], "relat": 23, "executionprofilehandl": [23, 26], "former": 23, "simpli": [23, 29, 41, 44, 60], "immut": 23, "latter": 23, "particular": [23, 28, 29], "moment": [23, 31], "point": 23, "dure": [23, 31, 32, 56], "lifetim": 23, "assign": [23, 25, 26, 28], "At": 23, "remap": 23, "switch": [23, 26, 27], "characterist": 23, "speculative_execut": [24, 54, 55], "simplespeculativeexecutionpolici": [24, 55], "serialconsist": [24, 35], "load_balanc": [24, 28, 29], "defaultpolici": [24, 29], "retry_polici": [24, 49, 50, 51], "fallthroughretrypolici": [24, 51], "sync": [24, 29, 32, 54, 55, 60], "serial_consist": 24, "load_balancing_polici": [24, 29], "speculative_execution_polici": [24, 54, 55], "max_retry_count": [24, 54, 55], "retry_interv": [24, 55], "from_milli": [24, 55], "100": [24, 55], "profil": [25, 27, 29, 49], "either": [25, 60], "overridden": 25, "upon": [25, 40], "creation": [25, 56], "moreov": 25, "ha": [25, 28, 32, 41, 43, 50, 52, 54, 56, 60, 61], "higher": 25, "directli": [25, 32], "In": [25, 28, 29, 32, 36, 37, 41, 43, 45, 47, 50, 53, 60], "over": [25, 32, 36], "recap": 25, "session_profil": 25, "One": [25, 26, 34, 35, 37, 41, 50], "query_profil": 25, "appli": [25, 28, 32, 37, 52], "therefor": [25, 40, 43, 50], "set_consist": [25, 34, 35, 37, 41], "affect": [26, 28, 32, 36, 41], "been": [26, 40, 50], "quick": [26, 27], "session1": 26, "handle1": 26, "profile1": 26, "statement1": 26, "statement2": 26, "handle2": 26, "profile2": 26, "becom": [26, 28, 35], "yield": [26, 42], "power": 26, "modifi": [26, 34], "your": [26, 29, 36, 44], "below": [26, 32, 42, 50, 53], "abov": [26, 28, 54], "code": [26, 27, 29], "map_to_another_profil": 26, "book": 27, "written": [27, 30, 32], "optim": [27, 29, 56], "compat": [27, 32, 37], "apach": 27, "lesson": 27, "univers": 27, "api": [27, 34, 35, 37, 41], "start": [27, 30, 36, 48, 55, 56, 60], "up": [27, 43, 47, 50], "project": [27, 47], "migrat": [27, 40], "guid": 27, "older": 27, "cluster": [27, 28, 29, 36, 37, 41, 50, 53], "prepar": [27, 28, 29, 36, 38, 41, 49, 50, 51, 52, 58, 61], "batch": [27, 32, 35, 38, 61], "page": [27, 31, 32, 37, 38, 41], "execut": [27, 28, 29, 30, 32, 34, 36, 39, 40, 41, 42, 49, 50, 51, 57], "onc": [27, 32, 34, 38, 53, 60], "column": [27, 32, 39, 44, 53], "what": [27, 43, 60, 61], "fail": [27, 29, 32, 39, 50, 52, 60], "idempot": 27, "metric": [27, 54], "statist": [27, 29], "latenc": [27, 29, 31, 43, 56], "log": [27, 50], "view": [27, 30, 53], "integr": 27, "produc": [27, 32], "trace": [27, 30, 45, 60], "inspect": 27, "local": [28, 35, 42], "mode": 28, "defaultpolicybuild": 28, "rack": 28, "is_token_awar": 28, "permit_dc_failov": 28, "latency_awar": 28, "desir": 28, "default_polici": 28, "prefer_datacenter_and_rack": 28, "dc1": 28, "rack1": 28, "token_awar": 28, "priorit": 28, "locat": 28, "my_dc": 28, "treat": [28, 44], "remot": 28, "zone": 28, "too": 28, "first": [28, 29, 32, 34, 36, 37, 39, 43, 55, 56, 60], "replica": [28, 29, 37, 50], "similarli": 28, "disabl": [28, 29, 32, 40], "includ": [28, 29, 32, 34, 47, 60], "exclud": 28, "even": [28, 34, 50], "aliv": [28, 50], "serv": 28, "event": [28, 57, 58, 59, 60, 61], "outag": 28, "network": 28, "failur": [28, 29, 40, 52], "unavail": [28, 50], "client": [28, 48], "longer": 28, "access": [28, 31, 43, 54, 60], "permit": 28, "due": [28, 34], "constraint": 28, "mechan": [28, 40], "partit": [28, 37], "across": 28, "want": [28, 32, 40, 44], "being": [28, 29, 32, 34, 39, 50], "help": [28, 29, 39, 49], "minim": 28, "improv": [28, 37], "ensur": [28, 32, 39], "much": [28, 32, 37], "within": [28, 35], "assum": 28, "significantli": 28, "scalabl": 28, "built": [28, 32], "reduc": 28, "overhead": [28, 32], "throughput": 28, "pleas": [28, 35, 48], "penalis": 28, "whose": 28, "measur": 28, "recent": 28, "averag": [28, 31], "classifi": 28, "behind": 28, "update_r": 28, "global": [28, 30, 42], "minimum": 28, "comput": [28, 29, 37], "wors": [28, 43], "exclusion_threshold": 28, "retry_period": 28, "involv": 28, "put": [28, 34, 45], "end": [28, 43, 60], "often": 28, "truli": 28, "benefici": 28, "faster": 28, "lag": 28, "worsen": [28, 37, 41], "warn": [28, 30, 34, 36, 37, 41], "NOT": [28, 30, 35, 40, 46], "prior": 28, "benchmark": 28, "prove": 28, "impact": 28, "caution": 28, "latencyawarenessbuild": 28, "latency_awareness_build": 28, "minimum_measur": 28, "200": [28, 40], "further": 28, "customis": 28, "cours": 28, "prefer_datacent": 28, "down": [28, 29, 40], "And": 28, "ones": [28, 32, 61], "prioriti": 28, "shuffl": 28, "randomli": 28, "rotat": 28, "round": [28, 32, 36, 37, 41], "robin": 28, "index": 28, "optimis": 28, "lwt": 28, "ring": 28, "prevent": 28, "content": 28, "paxo": 28, "conflict": 28, "determin": [29, 50], "contact": 29, "gener": [29, 30, 32, 44], "state": [29, 43], "influenc": 29, "open": 29, "blacklist": 29, "host_filt": 29, "hostfilt": 29, "wide": 29, "target": 29, "pair": 29, "construct": 29, "essenti": [29, 32], "best": [29, 32, 34, 36, 43, 50], "might": [29, 32, 36, 37, 39, 40, 41, 44, 48, 49, 52, 60], "better": [29, 37, 38, 44, 50], "suit": 29, "our": [29, 32], "awar": [29, 34, 37, 41], "via": [29, 35], "sampl": [29, 60], "newli": [29, 32], "addit": [29, 32, 35, 36], "through": [29, 32], "level": [29, 35, 50], "basi": 29, "usual": 29, "unnecessari": 29, "entir": 29, "given": [29, 39, 42, 54], "rest": [29, 35], "call": [29, 32, 34, 53, 60], "layer": 29, "filter": [29, 45], "out": [29, 52, 60], "feedback": 29, "health": 29, "decis": [29, 60, 61], "hand": [29, 37], "messag": [29, 30, 48], "overload": 29, "avoid": [29, 39, 43], "again": [29, 32, 40], "until": [29, 42, 60], "recov": 29, "subscrib": [30, 45], "print": [30, 41, 45, 46, 53, 60], "collector": [30, 60], "rust_log": 30, "tracing_subscrib": 30, "fmt": 30, "init": 30, "IF": [30, 35, 46], "exist": [30, 32, 35, 46], "WITH": [30, 46], "replic": [30, 46, 53], "networktopologystrategi": [30, 46], "replication_factor": [30, 46], "folder": 30, "get_metr": 31, "total": 31, "nonpag": 31, "get_queries_num": 31, "get_queries_iter_num": 31, "occur": [31, 53], "get_errors_num": 31, "get_errors_iter_num": 31, "get_latency_avg_m": 31, "99": [31, 54], "9": 31, "percentil": [31, 56], "get_latency_percentile_m": 31, "bind": [32, 34, 44], "marker": [32, 34, 44], "untyp": 32, "form": 32, "safer": 32, "robust": 32, "interfac": 32, "check": [32, 44, 60], "against": [32, 56], "couldn": 32, "kind": 32, "valuelist": [32, 34], "serializedresult": 32, "write_to_request": 32, "buf": 32, "serializevalueserror": 32, "naiv": 32, "hope": [32, 60], "took": 32, "care": [32, 60], "db": 32, "side": [32, 42], "valid": 32, "worst": 32, "reinterpret": 32, "unintend": 32, "manner": 32, "problem": [32, 43], "robustli": 32, "intousertyp": 32, "cumbersom": 32, "deprec": 32, "fix": 32, "previou": [32, 36], "core": 32, "AND": 32, "ck": 32, "associ": 32, "legacybatchvalu": 32, "previous": 32, "batchvalu": [32, 34], "sourc": 32, "were": [32, 61], "notabl": [32, 35], "cach": [32, 34], "come": 32, "did": 32, "correctli": 32, "ergonom": 32, "counterpart": 32, "fromrow": [32, 39], "limit": [32, 40, 42], "properli": [32, 37, 38, 39], "similar": 32, "rework": 32, "plan": 32, "releas": 32, "worth": 32, "keep": 32, "bring": 32, "cannot": [32, 50], "right": 32, "shown": 32, "snippet": 32, "exact": 32, "effect": 32, "complet": [32, 42, 61], "analog": 32, "flavor": [32, 44], "enforce_ord": [32, 44], "skip_name_check": 32, "person": 32, "surnam": 32, "ag": [32, 39], "consider": 32, "concern": 32, "cachingsess": [32, 37], "alreadi": 32, "explain": 32, "done": [32, 34, 53, 60], "unprepar": [32, 34, 36], "skip": [32, 44, 61], "detect": 32, "noth": [32, 50], "along": [32, 60], "slowdown": 32, "incur": 32, "trip": [32, 36, 37, 41], "uniqu": 32, "roundtrip": [32, 43], "unaccept": 32, "beforehand": 32, "reus": 32, "align": 32, "sensit": 32, "easi": [32, 38], "occurr": [32, 50], "ad": [32, 41, 44], "atribut": 32, "procedur": 32, "larg": [32, 37, 41], "enough": 32, "codebas": 32, "complic": 32, "everyth": [32, 46], "remov": 32, "rather": [32, 40], "util": [32, 61], "newtyp": 32, "valueadapt": 32, "valuelistadapt": 32, "legacybatchvaluesadapt": 32, "zero": 32, "cost": [32, 37], "alloc": 32, "buffer": 32, "rewritten": 32, "shouldn": 32, "effici": 32, "legacybatchvaluesiter": 32, "write_next_to_request": 32, "natur": 32, "safe": 32, "convers": 32, "direct": [32, 42], "respect": 32, "impl_serialize_cql_via_valu": 32, "impl_serialize_row_via_value_list": 32, "11": [33, 60], "These": [34, 37], "delet": [34, 44], "prepared_stat": [34, 36, 37, 49, 50, 51, 52, 57, 58, 59], "preparedstat": [34, 35, 36, 37, 49, 50, 51, 52, 57, 58, 59], "append_stat": [34, 57], "tab": [34, 35, 37, 39, 41, 43, 44, 49, 50, 51, 52, 57, 58, 59], "b": [34, 36, 37, 39, 41, 43, 44], "manual": [34, 35, 41, 49, 50, 51, 52, 57, 58, 61], "6": [34, 36, 45], "bound": [34, 37, 41, 44], "batch_valu": 34, "5_i32": 34, "sequenti": [34, 60], "consid": 34, "instead": [34, 36, 37, 41, 43], "individu": 34, "simple_unprepared1": 34, "simple_unprepared2": 34, "prepared_batch": 34, "prepare_batch": 34, "1_i32": [34, 44], "2_i32": [34, 41, 44], "3_i32": 34, "4_i32": 34, "length": 34, "equal": 34, "trait": [34, 44, 52], "slice": [34, 44], "unit": [34, 44], "third": [34, 60], "express": 35, "serial_consistency_level": 35, "separ": [35, 61], "simplequeri": 35, "lai": 35, "condit": 35, "rememb": 35, "localseri": 35, "variant": [35, 36], "commonli": 35, "cross": 35, "overrid": 35, "ONE": [35, 41], "my_queri": [35, 41, 49, 50, 51, 52], "set_serial_consist": 35, "remain": 35, "ident": 35, "sometim": [36, 40, 50], "fit": [36, 38], "query_it": [36, 61], "execute_it": [36, 61], "fulli": [36, 38], "amort": 36, "stream": [36, 60], "streamext": [36, 58], "rows_stream": 36, "next_row_r": 36, "set_page_s": 36, "extract": 36, "That": 36, "left": 36, "off": [36, 42], "paged_queri": 36, "with_page_s": 36, "res1": 36, "res2": 36, "query_pag": 36, "paging_st": 36, "paged_prepar": 36, "execute_pag": 36, "benefit": 37, "offer": 37, "safeti": 37, "thank": 37, "metadata": [37, 53], "verifi": 37, "sure": [37, 44, 50], "destin": 37, "nativ": 37, "impli": 37, "choos": 37, "insight": 37, "later": 37, "work": [37, 41], "kei": [37, 46, 53], "don": [37, 39, 41, 43], "unpag": [37, 41], "heavi": [37, 41], "size": [37, 41], "least": [37, 50], "succe": [37, 50, 60], "inherit": 37, "especi": 37, "good": 37, "otherwis": [37, 40, 50], "hash": 37, "wrong": 37, "prepare_t": 37, "primari": [37, 46, 53], "wrong_prepar": 37, "54321": [37, 43], "matter": [37, 41, 60], "good_prepar": 37, "poor": 38, "primit": 38, "fast": 38, "addition": [38, 41], "special": 38, "asynchron": 38, "wish": [38, 40, 42], "queryresult": [39, 41, 57], "awkward": 39, "as_ref": [39, 44], "as_int": 39, "rowt": 39, "maybe_first_row_typ": 39, "first_row_typ": 39, "maybe_first_row": 39, "single_row_typ": 39, "first_row": 39, "result_not_row": 39, "bug": [39, 40], "first_int_v": 39, "no_row": 39, "str_or_nul": 39, "myrow": 39, "my_row": 39, "agre": 40, "automat": 40, "alter": 40, "wait": [40, 60], "never": [40, 41, 44, 51, 52], "slow": 40, "somebodi": 40, "sens": 40, "said": 40, "auto_await_schema_agr": 40, "await_schema_agr": 40, "ed": 40, "long": 40, "won": 40, "forev": 40, "sessionconfig": 40, "elaps": 40, "queryerror": [40, 42], "requesttimeout": [40, 42], "schema_vers": 40, "sleep": 40, "schema_agreement_interv": 40, "check_schema_agr": 40, "is_som": 40, "els": 40, "IN": 40, "anyth": [41, 61], "Into": 41, "constant": [41, 44, 55], "variabl": [41, 44], "fill": [41, 44], "easiest": [41, 48, 55], "integ": [41, 44], "text2": 41, "could": [41, 42, 43, 44], "lead": [41, 44], "sql": [41, 44], "inject": [41, 44], "pars": 41, "read_row": [41, 46], "place": 41, "With": 41, "immedi": 42, "continu": [42, 60], "still": [42, 43, 50, 60], "progress": 42, "interrupt": 42, "turn": 42, "no_timeout_profile_handl": 42, "block": 42, "indefinit": 42, "hang": 42, "truncat": 42, "three_sec_timeout_profile_handl": 42, "last": 42, "arriv": 42, "omit": 43, "cqlsh": 43, "my_keyspac": 43, "easili": 43, "other_keyspac": 43, "other_t": 43, "use_keyspac": 43, "test1": 43, "test2": 43, "argument": 43, "whether": 43, "slightli": 43, "half": 43, "insensit": 43, "altogeth": 43, "happen": [43, 50, 61], "lowercas": 43, "uppercas": 43, "serializerow": 44, "sort": 44, "intstr": 44, "int_str": 44, "42_i32": 44, "hello": [44, 45], "to_own": 44, "intstringcustom": 44, "first_valu": 44, "second_valu": 44, "int_string_custom": 44, "trail": 44, "coma": 44, "syntax": 44, "val": 44, "cqlvalu": 44, "avalu": 44, "bvalu": 44, "null_i32": 44, "tombston": 44, "maybeunset": 44, "suboptim": 44, "enum": 44, "unset_i32": 44, "instruct": 44, "myproject": 45, "13": 45, "36": 45, "14": 45, "r": 45, "readi": [46, 48], "small": 46, "extab": 46, "topic": 47, "docker": 47, "imag": 48, "linux": 48, "sudo": 48, "rm": 48, "p": 48, "smp": 48, "download": 48, "minut": 48, "listen": 48, "172": 48, "stop": 48, "press": 48, "ctrl": 48, "found": 48, "dockerhub": 48, "high": [49, 52], "chanc": [49, 50, 52], "datastax": [49, 50], "java": [49, 50], "defaultretrypolici": [49, 50], "set_retry_polici": 49, "lower": [50, 52], "bewar": 50, "break": 50, "guarante": 50, "word": 50, "quorum": 50, "preced": 50, "understood": 50, "highli": 50, "But": 50, "top": 50, "respond": [50, 60], "greater": 50, "writetyp": 50, "unloggedbatch": 50, "acknowledg": 50, "furthermor": 50, "ignor": 50, "except": 50, "rule": 50, "eachquorum": 50, "reach": 50, "overal": 50, "assumpt": 50, "host": [50, 54], "coordin": 50, "know": 50, "thu": 50, "silent": 50, "persist": 50, "idea": 50, "thing": 50, "someth": 50, "risk": 50, "stale": 50, "downgrading_consistency_retry_polici": 50, "downgradingconsistencyretrypolici": 50, "falthroughretrypolici": 51, "straight": [51, 52], "decid": [52, 60], "fallthrough": 52, "downgrad": 52, "behav": 52, "retrypolici": 52, "retrysess": 52, "increas": 52, "danger": 52, "figur": 52, "set_is_idempot": 52, "present": 53, "demand": 53, "newest": 53, "refresh_metadata": 53, "snapshot": 53, "examin": 53, "obtain": [53, 61], "belong": 53, "materi": 53, "strategi": [53, 56], "definit": 53, "partition": 53, "show": 53, "cluster_data": 53, "get_cluster_data": 53, "get_keyspace_info": 53, "keyspace_nam": 53, "keyspace_info": 53, "ttabl": 53, "tview": 53, "tudt": 53, "user_defined_typ": 53, "trigger": 54, "percentilespeculativeexecutionpolici": 54, "execution_profil": [54, 55], "delai": 55, "count": 55, "techniqu": 56, "pre": 56, "emptiv": 56, "repli": 56, "tracing_id": [57, 58, 59, 61], "tracinginfo": [57, 58, 59, 61], "set_trac": [57, 58, 59], "system_trac": [57, 58, 59, 61], "tracing_info": [57, 58, 59], "get_tracing_info": [57, 58, 59, 61], "subsequ": 58, "rowiter": 58, "row_iter": 58, "_row": 58, "get_tracing_id": 58, "prepare_tracing_id": 59, "to_prepar": 59, "fiber": 60, "historycollector": 60, "history_listen": 60, "set_history_listen": 60, "save": 60, "_ignore_error": 60, "structured_histori": 60, "clone_structured_histori": 60, "didn": 60, "encount": 60, "difficulti": 60, "start_tim": 60, "2022": 60, "25": 60, "21": 60, "50": 60, "445075147": 60, "445151628": 60, "447444362": 60, "447447970": 60, "had": 60, "troubl": 60, "26": 60, "15": 60, "28": 60, "525367409": 60, "219": 60, "525409294": 60, "yet": 60, "537074167": 60, "217": 60, "537126083": 60, "548050242": 60, "218": 60, "548089083": 60, "590052778": 60, "590078119": 60, "understand": 60, "answer": 60, "consult": 60, "made": [60, 61], "tri": 60, "quicker": 60, "spawn": 60, "wasn": 60, "acquir": 60, "analyz": 60, "structur": 60, "monitor": 61, "signifi": 61, "went": 61, "go": 61, "insid": 61, "think": 61}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"authent": 0, "import": 0, "The": 0, "default": [0, 32, 49], "credenti": 0, "ar": 0, "sent": 0, "plain": 0, "text": [0, 14], "server": 0, "For": 0, "thi": 0, "reason": 0, "i": [0, 32, 40], "highli": 0, "recommend": 0, "us": [0, 2, 3, 39, 43, 48], "conjunct": 0, "client": 0, "node": [0, 28], "encrypt": 0, "ssl": 0, "trust": 0, "network": 0, "environ": 0, "custom": [0, 32, 39, 60], "compress": 1, "connect": [2, 46], "cluster": 2, "best": 2, "practic": 2, "session": [2, 37, 58, 59], "metadata": 2, "scylla": [2, 27, 48], "cloud": 2, "serverless": 2, "tl": 3, "enabl": 3, "featur": 3, "blob": 5, "list": [6, 32], "set": [6, 22, 25], "map": 6, "counter": 7, "data": [8, 39, 44], "type": [8, 19, 39, 44], "date": 9, "cqldate": 9, "chrono": [9, 15, 16], "naived": 9, "time": [9, 15, 16], "decim": 10, "valu": [10, 21, 32, 34, 39, 41, 44], "cqldecim": 10, "bigdecim": 10, "durat": 11, "inet": 12, "bool": 13, "tinyint": 13, "smallint": 13, "int": 13, "bigint": [13, 21], "float": 13, "doubl": 13, "ascii": 14, "varchar": 14, "cqltime": 15, "naivetim": 15, "timestamp": 16, "cqltimestamp": 16, "datetim": 16, "offsetdatetim": 16, "timeuuid": 17, "creat": [17, 22, 28, 45], "your": 17, "own": 17, "tupl": 18, "user": 19, "defin": 19, "uuid": 20, "varint": 21, "num_bigint": 21, "cqlvarint": 21, "exampl": [21, 22, 24, 25, 26, 31, 36, 49, 50, 51, 54, 55, 60], "profil": [22, 23, 24, 26], "execut": [23, 25, 26, 37, 54, 55, 56, 60, 61], "all": 24, "option": [24, 34, 37], "support": 24, "prioriti": 25, "remap": 26, "handl": 26, "rust": 27, "driver": [27, 31, 60], "other": [27, 39, 44], "document": 27, "content": 27, "defaultpolici": 28, "semant": 28, "prefer": 28, "datacent": 28, "failov": 28, "token": 28, "awar": 28, "latenc": 28, "order": 28, "produc": 28, "plan": [28, 29], "load": 29, "balanc": 29, "introduct": 29, "polici": [29, 49, 50, 51, 52], "configur": [29, 36, 52], "loadbalancingpolici": 29, "trait": [29, 32, 60], "pick": 29, "fallback": 29, "on_query_success": 29, "on_query_failur": 29, "log": 30, "metric": 31, "collect": [31, 60], "adjust": 32, "code": [32, 60], "chang": 32, "serial": 32, "api": 32, "introduc": 32, "0": 32, "11": 32, "background": 32, "old": 32, "v": 32, "new": 32, "migrat": [32, 33], "scenario": 32, "differ": 32, "behavior": 32, "serializerow": 32, "serializecql": 32, "macro": 32, "prepar": [32, 34, 37, 57, 59], "mandatori": 32, "non": 32, "empti": 32, "from": 32, "gradual": 32, "convert": 32, "an": 32, "object": 32, "implement": 32, "guid": 33, "batch": [34, 57], "statement": 34, "perform": [34, 36, 37, 41], "lightweight": 35, "transact": 35, "lwt": 35, "queri": [35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 52, 57, 58, 60, 61], "format": 35, "page": [36, 58], "size": 36, "pass": 36, "state": 36, "manual": [36, 40], "make": 38, "result": [39, 41], "basic": 39, "represent": 39, "pars": 39, "into_typ": 39, "conveni": 39, "method": 39, "null": [39, 44], "row": 39, "struct": 39, "schema": [40, 53], "agreement": 40, "autom": 40, "await": 40, "interv": 40, "check": 40, "now": 40, "simpl": [41, 46, 55, 57], "first": 41, "argument": 41, "second": 41, "timeout": 42, "keyspac": 43, "multipl": 43, "onc": 43, "case": 43, "sensit": 43, "unset": 44, "project": 45, "run": [46, 48], "quick": 47, "start": 47, "docker": 48, "more": 48, "inform": 48, "retri": [49, 50, 51, 52], "downgrad": 50, "consist": 50, "fallthrough": 51, "idempot": 52, "fetch": 53, "inspect": 53, "percentil": 54, "specul": [54, 55, 56, 60], "trace": [57, 58, 59, 61], "query_it": 58, "execute_it": 58, "histori": [60, 61], "output": 60, "how": 60, "No": 60, "structuredhistori": 60, "historylisten": 60}, "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": {"List, Set, Map": [[6, "list-set-map"]], "List": [[6, "list"]], "Set": [[6, "set"]], "Map": [[6, "map"]], "Data Types": [[8, "data-types"]], "Connecting to the cluster": [[2, "connecting-to-the-cluster"]], "Best practices for using Session": [[2, "best-practices-for-using-session"]], "Metadata": [[2, "metadata"]], "Scylla Cloud Serverless": [[2, "scylla-cloud-serverless"]], "Compression": [[1, "compression"]], "Date": [[9, "date"]], "CqlDate": [[9, "cqldate"]], "chrono::NaiveDate": [[9, "chrono-naivedate"]], "time::Date": [[9, "time-date"]], "Authentication": [[0, "authentication"]], "Important: The default authentication credentials are sent in plain text to the server. For this reason, it is highly recommended that this be used in conjunction with client-to-node encryption (SSL), or in a trusted network environment.": [[0, "important-the-default-authentication-credentials-are-sent-in-plain-text-to-the-server-for-this-reason-it-is-highly-recommended-that-this-be-used-in-conjunction-with-client-to-node-encryption-ssl-or-in-a-trusted-network-environment"]], "Custom Authentication": [[0, "custom-authentication"]], "TLS": [[3, "tls"]], "Enabling feature": [[3, "enabling-feature"]], "Using TLS": [[3, "using-tls"]], "Counter": [[7, "counter"]], "Blob": [[5, "blob"]], "Duration": [[11, "duration"]], "Decimal": [[10, "decimal"]], "value::CqlDecimal": [[10, "value-cqldecimal"]], "bigdecimal::BigDecimal": [[10, "bigdecimal-bigdecimal"]], "Timeuuid": [[17, "timeuuid"]], "Creating your own Timeuuid": [[17, "creating-your-own-timeuuid"]], "Time": [[15, "time"]], "CqlTime": [[15, "cqltime"]], "chrono::NaiveTime": [[15, "chrono-naivetime"]], "time::Time": [[15, "time-time"]], "Creating a profile and setting it": [[22, "creating-a-profile-and-setting-it"]], "Example": [[22, "example"], [22, "id1"], [22, "id2"], [21, "example"], [26, "example"], [25, "example"], [24, "example"], [31, "example"], [54, "example"], [55, "example"]], "Timestamp": [[16, "timestamp"]], "CqlTimestamp": [[16, "cqltimestamp"]], "chrono::DateTime": [[16, "chrono-datetime"]], "time::OffsetDateTime": [[16, "time-offsetdatetime"]], "Varint": [[21, "varint"]], "num_bigint::BigInt": [[21, "num-bigint-bigint"]], "value::CqlVarint": [[21, "value-cqlvarint"]], "Bool, Tinyint, Smallint, Int, Bigint, Float, Double": [[13, "bool-tinyint-smallint-int-bigint-float-double"]], "Bool": [[13, "bool"]], "Tinyint": [[13, "tinyint"]], "Smallint": [[13, "smallint"]], "Int": [[13, "int"]], "Bigint": [[13, "bigint"]], "Float": [[13, "float"]], "Double": [[13, "double"]], "User defined types": [[19, "user-defined-types"]], "Inet": [[12, "inet"]], "Tuple": [[18, "tuple"]], "Execution profiles": [[23, "execution-profiles"]], "Uuid": [[20, "uuid"]], "Ascii, Text, Varchar": [[14, "ascii-text-varchar"]], "Prepared query": [[37, "prepared-query"]], "Session::prepare": [[37, "session-prepare"]], "Session::execute": [[37, "session-execute"]], "Query options": [[37, "query-options"]], "Performance": [[37, "performance"], [36, "performance"], [41, "performance"], [34, "performance"]], "Creating a project": [[45, "creating-a-project"]], "Making queries": [[38, "making-queries"]], "Quick Start": [[47, "quick-start"]], "Query timeouts": [[42, "query-timeouts"]], "Schema agreement": [[40, "schema-agreement"]], "Automated awaiting schema agreement": [[40, "automated-awaiting-schema-agreement"]], "Manually awaiting schema agreement": [[40, "manually-awaiting-schema-agreement"]], "Interval of checking for schema agreement": [[40, "interval-of-checking-for-schema-agreement"]], "Checking if schema is in agreement now": [[40, "checking-if-schema-is-in-agreement-now"]], "Paged query": [[36, "paged-query"]], "Examples": [[36, "examples"], [49, "examples"], [50, "examples"], [51, "examples"]], "Configuring page size": [[36, "configuring-page-size"]], "Passing the paging state manually": [[36, "passing-the-paging-state-manually"]], "Connecting and running a simple query": [[46, "connecting-and-running-a-simple-query"]], "USE keyspace": [[43, "use-keyspace"]], "Multiple use queries at once": [[43, "multiple-use-queries-at-once"]], "Case sensitivity": [[43, "case-sensitivity"]], "Query result": [[39, "query-result"], [41, "query-result"]], "Basic representation": [[39, "basic-representation"]], "Parsing using into_typed": [[39, "parsing-using-into-typed"]], "Parsing using convenience methods": [[39, "parsing-using-convenience-methods"]], "NULL values": [[39, "null-values"], [44, "null-values"]], "Parsing row as a custom struct": [[39, "parsing-row-as-a-custom-struct"]], "Other data types": [[39, "other-data-types"], [44, "other-data-types"]], "Simple query": [[41, "simple-query"]], "First argument - the query": [[41, "first-argument-the-query"]], "Second argument - the values": [[41, "second-argument-the-values"]], "Query values": [[44, "query-values"]], "Unset values": [[44, "unset-values"]], "Logging": [[30, "logging"]], "Adjusting code to changes in serialization API introduced in 0.11": [[32, "adjusting-code-to-changes-in-serialization-api-introduced-in-0-11"]], "Background": [[32, "background"]], "Old vs. new": [[32, "old-vs-new"]], "Migration scenarios": [[32, "migration-scenarios"]], "Different default behavior in SerializeRow/SerializeCql macros": [[32, "different-default-behavior-in-serializerow-serializecql-macros"]], "Preparing is mandatory with a non-empty list of values": [[32, "preparing-is-mandatory-with-a-non-empty-list-of-values"]], "Migrating from old to new traits gradually": [[32, "migrating-from-old-to-new-traits-gradually"]], "Converting an object implementing an old trait to a new trait": [[32, "converting-an-object-implementing-an-old-trait-to-a-new-trait"]], "Custom implementations of old traits": [[32, "custom-implementations-of-old-traits"]], "Remapping execution profile handles": [[26, "remapping-execution-profile-handles"]], "Load balancing": [[29, "load-balancing"]], "Introduction": [[29, "introduction"]], "Plan": [[29, "plan"]], "Policy": [[29, "policy"]], "Configuration": [[29, "configuration"]], "LoadBalancingPolicy trait": [[29, "loadbalancingpolicy-trait"]], "pick and fallback:": [[29, "pick-and-fallback"]], "on_query_success and on_query_failure:": [[29, "on-query-success-and-on-query-failure"]], "DefaultPolicy": [[28, "defaultpolicy"]], "Creating a DefaultPolicy": [[28, "creating-a-defaultpolicy"]], "Semantics of DefaultPolicy": [[28, "semantics-of-defaultpolicy"]], "Preferences": [[28, "preferences"]], "Datacenter Failover": [[28, "datacenter-failover"]], "Token awareness": [[28, "token-awareness"]], "Latency awareness": [[28, "latency-awareness"]], "Creating a latency aware DefaultPolicy": [[28, "creating-a-latency-aware-defaultpolicy"]], "Node order in produced plans": [[28, "node-order-in-produced-plans"]], "Priorities of execution settings": [[25, "priorities-of-execution-settings"]], "Batch statement": [[34, "batch-statement"]], "Preparing a batch": [[34, "preparing-a-batch"]], "Batch options": [[34, "batch-options"]], "Batch values": [[34, "batch-values"]], "Migration guides": [[33, "migration-guides"]], "All options supported by a profile": [[24, "all-options-supported-by-a-profile"]], "Driver metrics": [[31, "driver-metrics"]], "Collected metrics:": [[31, "collected-metrics"]], "Scylla Rust Driver": [[27, "scylla-rust-driver"]], "Other documentation": [[27, "other-documentation"]], "Contents": [[27, "contents"]], "Lightweight transaction (LWT) query": [[35, "lightweight-transaction-lwt-query"]], "Format of the query": [[35, "format-of-the-query"]], "Query Execution History": [[60, "query-execution-history"], [61, "query-execution-history"]], "Example code": [[60, "example-code"]], "Output": [[60, "output"]], "How the driver executes queries": [[60, "how-the-driver-executes-queries"]], "No speculative execution": [[60, "no-speculative-execution"]], "Speculative execution": [[60, "speculative-execution"], [56, "speculative-execution"]], "StructuredHistory": [[60, "structuredhistory"]], "HistoryListener trait, custom history collecting": [[60, "historylistener-trait-custom-history-collecting"]], "Query tracing": [[61, "query-tracing"]], "Tracing": [[61, "tracing"]], "Retry policy configuration": [[52, "retry-policy-configuration"]], "Retry policies": [[52, "retry-policies"]], "Query idempotence": [[52, "query-idempotence"]], "Default retry policy": [[49, "default-retry-policy"]], "Tracing Session::prepare": [[59, "tracing-session-prepare"]], "Percentile speculative execution": [[54, "percentile-speculative-execution"]], "Tracing a paged query": [[58, "tracing-a-paged-query"]], "Tracing Session::query_iter": [[58, "tracing-session-query-iter"]], "Tracing Session::execute_iter": [[58, "tracing-session-execute-iter"]], "Schema": [[53, "schema"]], "Fetching schema": [[53, "fetching-schema"]], "Inspecting schema": [[53, "inspecting-schema"]], "Tracing a simple/prepared/batch query": [[57, "tracing-a-simple-prepared-batch-query"]], "Tracing a simple query": [[57, "tracing-a-simple-query"]], "Tracing a prepared query": [[57, "tracing-a-prepared-query"]], "Tracing a batch query": [[57, "tracing-a-batch-query"]], "Running Scylla using Docker": [[48, "running-scylla-using-docker"]], "Running scylla": [[48, "running-scylla"]], "More information": [[48, "more-information"]], "Downgrading consistency retry policy": [[50, "downgrading-consistency-retry-policy"]], "Simple speculative execution": [[55, "simple-speculative-execution"]], "Fallthrough retry policy": [[51, "fallthrough-retry-policy"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/main/sitemap.xml b/main/sitemap.xml new file mode 100644 index 0000000000..e4ff890666 --- /dev/null +++ b/main/sitemap.xml @@ -0,0 +1,2 @@ + +https://rust-driver.docs.scylladb.com/stable/connecting/authentication.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/compression.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/connecting.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/tls.htmlhttps://rust-driver.docs.scylladb.com/stable/contents.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/time.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/blob.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/collections.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/timestamp.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/timeuuid.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/counter.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/data-types.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/tuple.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/date.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/decimal.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/duration.htmlhttps://rust-driver.docs.scylladb.com/stable/load-balancing/load-balancing.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/inet.htmlhttps://rust-driver.docs.scylladb.com/stable/logging/logging.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/udt.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/primitive.htmlhttps://rust-driver.docs.scylladb.com/stable/metrics/metrics.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/uuid.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/text.htmlhttps://rust-driver.docs.scylladb.com/stable/migration-guides/0.11-serialization.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/varint.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/create-and-use.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/basic.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/execution-profiles.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/paged.htmlhttps://rust-driver.docs.scylladb.com/stable/migration-guides/migration-guides.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/maximal-example.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/batch.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/prepare.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/priority.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/lwt.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/remap.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/paged.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/query-history.htmlhttps://rust-driver.docs.scylladb.com/stable/index.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/tracing.htmlhttps://rust-driver.docs.scylladb.com/stable/load-balancing/default-policy.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/prepared.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/queries.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/result.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/usekeyspace.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/schema-agreement.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/values.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/simple.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/create-project.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/timeouts.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/example.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/quickstart.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/scylla-docker.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/default.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/downgrading-consistency.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/fallthrough.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/retry-policy.htmlhttps://rust-driver.docs.scylladb.com/stable/schema/schema.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/percentile.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/simple.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/speculative.htmlhttps://rust-driver.docs.scylladb.com/stable/genindex.htmlhttps://rust-driver.docs.scylladb.com/stable/404.htmlhttps://rust-driver.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/main/speculative-execution/percentile.html b/main/speculative-execution/percentile.html new file mode 100644 index 0000000000..0cad08400f --- /dev/null +++ b/main/speculative-execution/percentile.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Percentile speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Percentile speculative execution

      +

      This policy has access to Metrics shared with session, and triggers +speculative execution when the request to the current host is above a +given percentile.

      +
      +

      Example

      +

      To use this policy in Session:

      +
      use std::{sync::Arc, time::Duration};
      +use scylla::{
      +    Session,
      +    SessionBuilder,
      +    speculative_execution::PercentileSpeculativeExecutionPolicy,
      +    transport::execution_profile::ExecutionProfile,
      +};
      +
      +let policy = PercentileSpeculativeExecutionPolicy  {
      +    max_retry_count: 3,
      +    percentile: 99.0,
      +};
      +
      +let handle = ExecutionProfile::builder()
      +    .speculative_execution_policy(Some(Arc::new(policy)))
      +    .build()
      +    .into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .default_execution_profile_handle(handle)
      +    .build()
      +    .await?;
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/speculative-execution/simple.html b/main/speculative-execution/simple.html new file mode 100644 index 0000000000..022ad5284c --- /dev/null +++ b/main/speculative-execution/simple.html @@ -0,0 +1,664 @@ + + + + + + + + + + + + + Simple speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Simple speculative execution

      +

      The easiest speculative execution policy available. It starts another +execution of a query after constant delay of retry_interval and does at most +max_retry_count speculative query executions (not counting the first, +non-speculative one).

      +
      +

      Example

      +

      To use this policy in Session:

      +
      use std::{sync::Arc, time::Duration};
      +use scylla::{
      +    Session,
      +    SessionBuilder,
      +    speculative_execution::SimpleSpeculativeExecutionPolicy,
      +    transport::execution_profile::ExecutionProfile,
      +};
      +
      +let policy = SimpleSpeculativeExecutionPolicy {
      +    max_retry_count: 3,
      +    retry_interval: Duration::from_millis(100),
      +};
      +
      +let handle = ExecutionProfile::builder()
      +    .speculative_execution_policy(Some(Arc::new(policy)))
      +    .build()
      +    .into_handle();
      +
      +let session: Session = SessionBuilder::new()
      +    .known_node("127.0.0.1:9042")
      +    .default_execution_profile_handle(handle)
      +    .build()
      +    .await?;
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/speculative-execution/speculative.html b/main/speculative-execution/speculative.html new file mode 100644 index 0000000000..d564770c5a --- /dev/null +++ b/main/speculative-execution/speculative.html @@ -0,0 +1,629 @@ + + + + + + + + + + + + + Speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Speculative execution

      +

      Speculative query execution is an optimization technique where a driver +pre-emptively starts a second execution of a query against another node, +before the first node has replied.

      +

      There are multiple speculative execution strategies that the driver can use. +Speculative execution can be configured for the whole whole Session during +its creation.

      +

      Available speculative execution strategies:

      + +

      Speculative execution is not enabled by default, and currently only +non-iter session methods use it.

      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/tracing/basic.html b/main/tracing/basic.html new file mode 100644 index 0000000000..832d90afd7 --- /dev/null +++ b/main/tracing/basic.html @@ -0,0 +1,708 @@ + + + + + + + + + + + + + Tracing a simple/prepared/batch query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Tracing a simple/prepared/batch query

      +

      Simple query, prepared query and batch query +return a QueryResult which contains a tracing_id if tracing was enabled.

      +
      +

      Tracing a simple query

      +
      use scylla::query::Query;
      +use scylla::QueryResult;
      +use scylla::tracing::TracingInfo;
      +use uuid::Uuid;
      +
      +// Create a Query manually and enable tracing
      +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)");
      +query.set_tracing(true);
      +
      +let res: QueryResult = session.query(query, &[]).await?;
      +let tracing_id: Option<Uuid> = res.tracing_id;
      +
      +if let Some(id) = tracing_id {
      +    // Query tracing info from system_traces.sessions and system_traces.events
      +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
      +    println!("tracing_info: {:#?}", tracing_info);
      +}
      +
      +
      +
      +
      +

      Tracing a prepared query

      +
      use scylla::prepared_statement::PreparedStatement;
      +use scylla::QueryResult;
      +use scylla::tracing::TracingInfo;
      +use uuid::Uuid;
      +
      +// Prepare the query
      +let mut prepared: PreparedStatement = session
      +    .prepare("SELECT a FROM ks.tab")
      +    .await?;
      +
      +// Enable tracing for the prepared query
      +prepared.set_tracing(true);
      +
      +let res: QueryResult = session.execute(&prepared, &[]).await?;
      +let tracing_id: Option<Uuid> = res.tracing_id;
      +
      +if let Some(id) = tracing_id {
      +    // Query tracing info from system_traces.sessions and system_traces.events
      +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
      +    println!("tracing_info: {:#?}", tracing_info);
      +}
      +
      +
      +
      +
      +

      Tracing a batch query

      +
      use scylla::batch::Batch;
      +use scylla::QueryResult;
      +use scylla::tracing::TracingInfo;
      +use uuid::Uuid;
      +
      +// Create a batch statement
      +let mut batch: Batch = Default::default();
      +batch.append_statement("INSERT INTO ks.tab (a) VALUES(4)");
      +
      +// Enable tracing
      +batch.set_tracing(true);
      +
      +let res: QueryResult = session.batch(&batch, ((),)).await?;
      +let tracing_id: Option<Uuid> = res.tracing_id;
      +
      +if let Some(id) = tracing_id {
      +    // Query tracing info from system_traces.sessions and system_traces.events
      +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
      +    println!("tracing_info: {:#?}", tracing_info);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/tracing/paged.html b/main/tracing/paged.html new file mode 100644 index 0000000000..e1726bc98d --- /dev/null +++ b/main/tracing/paged.html @@ -0,0 +1,696 @@ + + + + + + + + + + + + + Tracing a paged query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Tracing a paged query

      +

      A paged query performs multiple simple/prepared queries to query subsequent pages.
      +If tracing is enabled the row iterator will contain a list of tracing ids for all performed queries.

      +
      +

      Tracing Session::query_iter

      +
      use scylla::query::Query;
      +use scylla::transport::iterator::RowIterator;
      +use scylla::tracing::TracingInfo;
      +use futures::StreamExt;
      +use uuid::Uuid;
      +
      +// Create a Query manually and enable tracing
      +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)");
      +query.set_tracing(true);
      +
      +// Create a paged query iterator and fetch pages
      +let mut row_iterator: RowIterator = session.query_iter(query, &[]).await?;
      +while let Some(_row) = row_iterator.next().await {
      +    // Receive rows
      +}
      +
      +// Now there are tracing ids for each performed query
      +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids();
      +
      +for id in tracing_ids {
      +    // Query tracing info from system_traces.sessions and system_traces.events
      +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
      +    println!("tracing_info: {:#?}", tracing_info);
      +}
      +
      +
      +
      +
      +

      Tracing Session::execute_iter

      +
      use scylla::prepared_statement::PreparedStatement;
      +use scylla::transport::iterator::RowIterator;
      +use scylla::tracing::TracingInfo;
      +use futures::StreamExt;
      +use uuid::Uuid;
      +
      +// Prepare the query
      +let mut prepared: PreparedStatement = session
      +    .prepare("SELECT a FROM ks.tab")
      +    .await?;
      +
      +// Enable tracing for the prepared query
      +prepared.set_tracing(true);
      +
      +// Create a paged query iterator and fetch pages
      +let mut row_iterator: RowIterator = session.execute_iter(prepared, &[]).await?;
      +while let Some(_row) = row_iterator.next().await {
      +    // Receive rows
      +}
      +
      +// Now there are tracing ids for each performed query
      +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids();
      +
      +for id in tracing_ids {
      +    // Query tracing info from system_traces.sessions and system_traces.events
      +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
      +    println!("tracing_info: {:#?}", tracing_info);
      +}
      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/tracing/prepare.html b/main/tracing/prepare.html new file mode 100644 index 0000000000..9f15fa9585 --- /dev/null +++ b/main/tracing/prepare.html @@ -0,0 +1,644 @@ + + + + + + + + + + + + + Tracing Session::prepare | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Tracing Session::prepare

      +

      Session::prepare prepares a query on all connections. If tracing is enabled for the Query to prepare, the resulting PreparedStatement will contain prepare_tracing_ids. prepare_tracing_ids is a list of tracing ids of prepare requests on all connections.

      +
      use scylla::query::Query;
      +use scylla::prepared_statement::PreparedStatement;
      +use scylla::tracing::TracingInfo;
      +use uuid::Uuid;
      +
      +// Prepare the query with tracing enabled
      +let mut to_prepare: Query = Query::new("SELECT a FROM ks.tab");
      +to_prepare.set_tracing(true);
      +
      +let mut prepared: PreparedStatement = session
      +    .prepare(to_prepare)
      +    .await?;
      +
      +// Now there are tracing ids for each prepare request
      +let tracing_ids: &[Uuid] = &prepared.prepare_tracing_ids;
      +
      +for id in tracing_ids {
      +    // Query tracing info from system_traces.sessions and system_traces.events
      +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
      +    println!("tracing_info: {:#?}", tracing_info);
      +}
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/tracing/query-history.html b/main/tracing/query-history.html new file mode 100644 index 0000000000..c5314d12f8 --- /dev/null +++ b/main/tracing/query-history.html @@ -0,0 +1,743 @@ + + + + + + + + + + + + + Query Execution History | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Query Execution History

      +

      The driver allows to collect history of query execution.
      +This history includes all requests sent, decisions to retry and speculative execution fibers started.

      +
      +

      Example code

      +
      use scylla::query::Query;
      +use scylla::history::{HistoryCollector, StructuredHistory};
      +use std::sync::Arc;
      +
      +// Create a query for which we would like to trace the history of its execution
      +let mut query: Query = Query::new("SELECT * FROM ks.t");
      +
      +// Create a history collector and pass it to the query
      +let history_listener = Arc::new(HistoryCollector::new());
      +query.set_history_listener(history_listener.clone());
      +
      +// Run the query, doesn't matter if it failed, the history will still be saved
      +let _ignore_error = session.query(query.clone(), ()).await;
      +
      +// Access the collected history and print it
      +let structured_history: StructuredHistory = history_listener.clone_structured_history();
      +println!("Query history: {}", structured_history);
      +
      +
      +

      To see more check out the example code

      +
      +
      +

      Output

      +

      Sample output for a query that didn’t encounter any difficulties:

      +
      === Query #0 ===
      +| start_time: 2022-08-25 11:21:50.445075147 UTC
      +| Non-speculative attempts:
      +| - Attempt #0 sent to 127.0.0.1:9042
      +|   request send time: 2022-08-25 11:21:50.445151628 UTC
      +|   Success at 2022-08-25 11:21:50.447444362 UTC
      +|
      +| Query successful at 2022-08-25 11:21:50.447447970 UTC
      +=================
      +
      +
      +

      Here’s output for a query that had some trouble - nodes didn’t respond and speculative execution decided to query others in parallel. +Finally the third node provided a response.

      +
      === Query #0 ===
      +| start_time: 2022-08-26 15:08:28.525367409 UTC
      +| Non-speculative attempts:
      +| - Attempt #0 sent to 127.0.0.219:9042
      +|   request send time: 2022-08-26 15:08:28.525409294 UTC
      +|   No result yet
      +|
      +|
      +| > Speculative fiber #0
      +| fiber start time: 2022-08-26 15:08:28.537074167 UTC
      +| - Attempt #0 sent to 127.0.0.217:9042
      +|   request send time: 2022-08-26 15:08:28.537126083 UTC
      +|   No result yet
      +|
      +|
      +| > Speculative fiber #1
      +| fiber start time: 2022-08-26 15:08:28.548050242 UTC
      +| - Attempt #0 sent to 127.0.0.218:9042
      +|   request send time: 2022-08-26 15:08:28.548089083 UTC
      +|   Success at 2022-08-26 15:08:28.590052778 UTC
      +|
      +| Query successful at 2022-08-26 15:08:28.590078119 UTC
      +=================
      +
      +
      +
      +
      +

      How the driver executes queries

      +

      To read the output it’s useful to understand more about how the driver executes queries.

      +
      +

      No speculative execution

      +

      Without speculative execution the driver performs many attempts sequentially until one of them succeeds. +A single attempt consists of sending a request to some node and waiting for the answer. +In case of an error the driver consults the retry policy to decide what to do next. +The decision might be to fail the query, retry on the same node, another node, change query parameters, etc. +Once the decision is made either the query fails or another attempt is started. This continues until the query ends.

      +
      +
      +

      Speculative execution

      +

      When speculative execution is enabled at first the driver doesn’t care about it - it does the attempts sequentially and tries to get an answer. +However once a specified amount of time has passed it will decide to try new attempts in parallel +hoping that another node will be able to answer quicker. +This is done by spawning a speculative fiber. Each spawned fiber performs sequential attempts just like in non-speculative execution. +Many fibers can be spawned if the answer wasn’t acquired in time.

      +
      +
      +

      StructuredHistory

      +

      StructuredHistory +is a history representation that represents the history by listing attempts for each speculative fiber.

      +
      +
      +
      +

      HistoryListener trait, custom history collecting

      +

      History can be collected by any struct implementing the +HistoryListener trait.

      +

      The implementation of HistoryListener provided by this crate is the +HistoryCollector. +HistoryCollector simply collects all events along with their timestamps.

      +

      Information collected by HistoryCollector is just a stream of events, in order to analyze it it’s possible +to convert it to a structured representation. +StructuredHistory +can be created by calling HistoryCollector::clone_structured_history().

      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/main/tracing/tracing.html b/main/tracing/tracing.html new file mode 100644 index 0000000000..bfe7187679 --- /dev/null +++ b/main/tracing/tracing.html @@ -0,0 +1,655 @@ + + + + + + + + + + + + + Query tracing | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
      +
      + Menu +
      +
      +
      +
      +
      + + +
      +

      Caution

      +

      + + You're viewing documentation for an unstable version of Scylla Rust Driver. + + Switch to the latest stable version. +

      +
      + + + +
      + +
      + +
      +

      Query tracing

      +

      The driver has utilities for monitoring the execution of queries. +There are two separate ways to get information about what happened with a query: Tracing and Query Execution History.

      +
      +

      Tracing

      +

      Tracing is a feature provided by Scylla. When sending a query we can set a flag that signifies that we would like it to be traced. +After completing the query Scylla provides a tracing_id which can be used to fetch information about it - which nodes it was sent to, what operations were performed etc.

      +

      Queries that support tracing:

      + +

      After obtaining the tracing id you can use Session::get_tracing_info() to query tracing information.
      +TracingInfo contains values that are the same in Scylla and Cassandra®, skipping any database-specific ones.
      +If TracingInfo does not contain some needed value it’s possible to query it manually from the tables +system_traces.sessions and system_traces.events

      +
      +
      +

      Query Execution History

      +

      Tracing provides information about how the query execution went on database nodes, but it doesn’t say anything about what was going on inside the driver.
      +This is what query execution history was made for.

      +

      It allows to follow what the driver was thinking - all query attempts, retry decisions, speculative executions. +More information is available in the Query Execution History chapter.

      +
      +
      +
      +
      + + +
      + + + + + + + +
      + +
      + + + + +
      + + + + + + + \ No newline at end of file diff --git a/stable/.buildinfo b/stable/.buildinfo new file mode 100644 index 0000000000..f449ca7ef5 --- /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: e91989ea1d62495a002d253b0d12d915 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/stable/.doctrees/connecting/authentication.doctree b/stable/.doctrees/connecting/authentication.doctree new file mode 100644 index 0000000000..31e02ee7ce Binary files /dev/null and b/stable/.doctrees/connecting/authentication.doctree differ diff --git a/stable/.doctrees/connecting/compression.doctree b/stable/.doctrees/connecting/compression.doctree new file mode 100644 index 0000000000..c99257bd74 Binary files /dev/null and b/stable/.doctrees/connecting/compression.doctree differ diff --git a/stable/.doctrees/connecting/connecting.doctree b/stable/.doctrees/connecting/connecting.doctree new file mode 100644 index 0000000000..231b791b8d Binary files /dev/null and b/stable/.doctrees/connecting/connecting.doctree differ diff --git a/stable/.doctrees/connecting/tls.doctree b/stable/.doctrees/connecting/tls.doctree new file mode 100644 index 0000000000..6824afed76 Binary files /dev/null and b/stable/.doctrees/connecting/tls.doctree differ diff --git a/stable/.doctrees/contents.doctree b/stable/.doctrees/contents.doctree new file mode 100644 index 0000000000..db46b97b4c Binary files /dev/null and b/stable/.doctrees/contents.doctree differ diff --git a/stable/.doctrees/data-types/blob.doctree b/stable/.doctrees/data-types/blob.doctree new file mode 100644 index 0000000000..7d2c8f8b97 Binary files /dev/null and b/stable/.doctrees/data-types/blob.doctree differ diff --git a/stable/.doctrees/data-types/collections.doctree b/stable/.doctrees/data-types/collections.doctree new file mode 100644 index 0000000000..89c0004ecc Binary files /dev/null and b/stable/.doctrees/data-types/collections.doctree differ diff --git a/stable/.doctrees/data-types/counter.doctree b/stable/.doctrees/data-types/counter.doctree new file mode 100644 index 0000000000..5ed5c3898b Binary files /dev/null and b/stable/.doctrees/data-types/counter.doctree differ diff --git a/stable/.doctrees/data-types/data-types.doctree b/stable/.doctrees/data-types/data-types.doctree new file mode 100644 index 0000000000..52e410f871 Binary files /dev/null and b/stable/.doctrees/data-types/data-types.doctree differ diff --git a/stable/.doctrees/data-types/date.doctree b/stable/.doctrees/data-types/date.doctree new file mode 100644 index 0000000000..2c0d9d2d7f Binary files /dev/null and b/stable/.doctrees/data-types/date.doctree differ diff --git a/stable/.doctrees/data-types/decimal.doctree b/stable/.doctrees/data-types/decimal.doctree new file mode 100644 index 0000000000..daf508d6f5 Binary files /dev/null and b/stable/.doctrees/data-types/decimal.doctree differ diff --git a/stable/.doctrees/data-types/duration.doctree b/stable/.doctrees/data-types/duration.doctree new file mode 100644 index 0000000000..ff95dd0f6a Binary files /dev/null and b/stable/.doctrees/data-types/duration.doctree differ diff --git a/stable/.doctrees/data-types/inet.doctree b/stable/.doctrees/data-types/inet.doctree new file mode 100644 index 0000000000..57887a3c17 Binary files /dev/null and b/stable/.doctrees/data-types/inet.doctree differ diff --git a/stable/.doctrees/data-types/primitive.doctree b/stable/.doctrees/data-types/primitive.doctree new file mode 100644 index 0000000000..ecda93f419 Binary files /dev/null and b/stable/.doctrees/data-types/primitive.doctree differ diff --git a/stable/.doctrees/data-types/text.doctree b/stable/.doctrees/data-types/text.doctree new file mode 100644 index 0000000000..6cd9048744 Binary files /dev/null and b/stable/.doctrees/data-types/text.doctree differ diff --git a/stable/.doctrees/data-types/time.doctree b/stable/.doctrees/data-types/time.doctree new file mode 100644 index 0000000000..67755869c6 Binary files /dev/null and b/stable/.doctrees/data-types/time.doctree differ diff --git a/stable/.doctrees/data-types/timestamp.doctree b/stable/.doctrees/data-types/timestamp.doctree new file mode 100644 index 0000000000..16918f1498 Binary files /dev/null and b/stable/.doctrees/data-types/timestamp.doctree differ diff --git a/stable/.doctrees/data-types/timeuuid.doctree b/stable/.doctrees/data-types/timeuuid.doctree new file mode 100644 index 0000000000..fc32fea5fb Binary files /dev/null and b/stable/.doctrees/data-types/timeuuid.doctree differ diff --git a/stable/.doctrees/data-types/tuple.doctree b/stable/.doctrees/data-types/tuple.doctree new file mode 100644 index 0000000000..1a448c46df Binary files /dev/null and b/stable/.doctrees/data-types/tuple.doctree differ diff --git a/stable/.doctrees/data-types/udt.doctree b/stable/.doctrees/data-types/udt.doctree new file mode 100644 index 0000000000..f2122184fe Binary files /dev/null and b/stable/.doctrees/data-types/udt.doctree differ diff --git a/stable/.doctrees/data-types/uuid.doctree b/stable/.doctrees/data-types/uuid.doctree new file mode 100644 index 0000000000..79731ed417 Binary files /dev/null and b/stable/.doctrees/data-types/uuid.doctree differ diff --git a/stable/.doctrees/data-types/varint.doctree b/stable/.doctrees/data-types/varint.doctree new file mode 100644 index 0000000000..d40f970c67 Binary files /dev/null and b/stable/.doctrees/data-types/varint.doctree differ diff --git a/stable/.doctrees/environment.pickle b/stable/.doctrees/environment.pickle new file mode 100644 index 0000000000..b997c493e7 Binary files /dev/null and b/stable/.doctrees/environment.pickle differ diff --git a/stable/.doctrees/execution-profiles/create-and-use.doctree b/stable/.doctrees/execution-profiles/create-and-use.doctree new file mode 100644 index 0000000000..8b0b664a94 Binary files /dev/null and b/stable/.doctrees/execution-profiles/create-and-use.doctree differ diff --git a/stable/.doctrees/execution-profiles/execution-profiles.doctree b/stable/.doctrees/execution-profiles/execution-profiles.doctree new file mode 100644 index 0000000000..6373fa65cc Binary files /dev/null and b/stable/.doctrees/execution-profiles/execution-profiles.doctree differ diff --git a/stable/.doctrees/execution-profiles/maximal-example.doctree b/stable/.doctrees/execution-profiles/maximal-example.doctree new file mode 100644 index 0000000000..5c73b82bb8 Binary files /dev/null and b/stable/.doctrees/execution-profiles/maximal-example.doctree differ diff --git a/stable/.doctrees/execution-profiles/priority.doctree b/stable/.doctrees/execution-profiles/priority.doctree new file mode 100644 index 0000000000..6b558975eb Binary files /dev/null and b/stable/.doctrees/execution-profiles/priority.doctree differ diff --git a/stable/.doctrees/execution-profiles/remap.doctree b/stable/.doctrees/execution-profiles/remap.doctree new file mode 100644 index 0000000000..717976068f Binary files /dev/null and b/stable/.doctrees/execution-profiles/remap.doctree differ diff --git a/stable/.doctrees/index.doctree b/stable/.doctrees/index.doctree new file mode 100644 index 0000000000..842b79f974 Binary files /dev/null and b/stable/.doctrees/index.doctree differ diff --git a/stable/.doctrees/load-balancing/default-policy.doctree b/stable/.doctrees/load-balancing/default-policy.doctree new file mode 100644 index 0000000000..37e31e5eff Binary files /dev/null and b/stable/.doctrees/load-balancing/default-policy.doctree differ diff --git a/stable/.doctrees/load-balancing/load-balancing.doctree b/stable/.doctrees/load-balancing/load-balancing.doctree new file mode 100644 index 0000000000..6068cf9c4b Binary files /dev/null and b/stable/.doctrees/load-balancing/load-balancing.doctree differ diff --git a/stable/.doctrees/logging/logging.doctree b/stable/.doctrees/logging/logging.doctree new file mode 100644 index 0000000000..d1ca2d6d64 Binary files /dev/null and b/stable/.doctrees/logging/logging.doctree differ diff --git a/stable/.doctrees/metrics/metrics.doctree b/stable/.doctrees/metrics/metrics.doctree new file mode 100644 index 0000000000..2821901fb4 Binary files /dev/null and b/stable/.doctrees/metrics/metrics.doctree differ diff --git a/stable/.doctrees/migration-guides/0.11-serialization.doctree b/stable/.doctrees/migration-guides/0.11-serialization.doctree new file mode 100644 index 0000000000..6f20674761 Binary files /dev/null and b/stable/.doctrees/migration-guides/0.11-serialization.doctree differ diff --git a/stable/.doctrees/migration-guides/migration-guides.doctree b/stable/.doctrees/migration-guides/migration-guides.doctree new file mode 100644 index 0000000000..c695a5966a Binary files /dev/null and b/stable/.doctrees/migration-guides/migration-guides.doctree differ diff --git a/stable/.doctrees/queries/batch.doctree b/stable/.doctrees/queries/batch.doctree new file mode 100644 index 0000000000..b9f0400750 Binary files /dev/null and b/stable/.doctrees/queries/batch.doctree differ diff --git a/stable/.doctrees/queries/lwt.doctree b/stable/.doctrees/queries/lwt.doctree new file mode 100644 index 0000000000..b24a1230e1 Binary files /dev/null and b/stable/.doctrees/queries/lwt.doctree differ diff --git a/stable/.doctrees/queries/paged.doctree b/stable/.doctrees/queries/paged.doctree new file mode 100644 index 0000000000..956dfc281c Binary files /dev/null and b/stable/.doctrees/queries/paged.doctree differ diff --git a/stable/.doctrees/queries/prepared.doctree b/stable/.doctrees/queries/prepared.doctree new file mode 100644 index 0000000000..8f44a3284f Binary files /dev/null and b/stable/.doctrees/queries/prepared.doctree differ diff --git a/stable/.doctrees/queries/queries.doctree b/stable/.doctrees/queries/queries.doctree new file mode 100644 index 0000000000..6856331bdf Binary files /dev/null and b/stable/.doctrees/queries/queries.doctree differ diff --git a/stable/.doctrees/queries/result.doctree b/stable/.doctrees/queries/result.doctree new file mode 100644 index 0000000000..3476670ab6 Binary files /dev/null and b/stable/.doctrees/queries/result.doctree differ diff --git a/stable/.doctrees/queries/schema-agreement.doctree b/stable/.doctrees/queries/schema-agreement.doctree new file mode 100644 index 0000000000..79e64c2ba3 Binary files /dev/null and b/stable/.doctrees/queries/schema-agreement.doctree differ diff --git a/stable/.doctrees/queries/simple.doctree b/stable/.doctrees/queries/simple.doctree new file mode 100644 index 0000000000..fe48620c93 Binary files /dev/null and b/stable/.doctrees/queries/simple.doctree differ diff --git a/stable/.doctrees/queries/timeouts.doctree b/stable/.doctrees/queries/timeouts.doctree new file mode 100644 index 0000000000..2687dcc996 Binary files /dev/null and b/stable/.doctrees/queries/timeouts.doctree differ diff --git a/stable/.doctrees/queries/usekeyspace.doctree b/stable/.doctrees/queries/usekeyspace.doctree new file mode 100644 index 0000000000..fb57149bea Binary files /dev/null and b/stable/.doctrees/queries/usekeyspace.doctree differ diff --git a/stable/.doctrees/queries/values.doctree b/stable/.doctrees/queries/values.doctree new file mode 100644 index 0000000000..72cd8d2845 Binary files /dev/null and b/stable/.doctrees/queries/values.doctree differ diff --git a/stable/.doctrees/quickstart/create-project.doctree b/stable/.doctrees/quickstart/create-project.doctree new file mode 100644 index 0000000000..daf2502510 Binary files /dev/null and b/stable/.doctrees/quickstart/create-project.doctree differ diff --git a/stable/.doctrees/quickstart/example.doctree b/stable/.doctrees/quickstart/example.doctree new file mode 100644 index 0000000000..09e61d7258 Binary files /dev/null and b/stable/.doctrees/quickstart/example.doctree differ diff --git a/stable/.doctrees/quickstart/quickstart.doctree b/stable/.doctrees/quickstart/quickstart.doctree new file mode 100644 index 0000000000..907bc8db03 Binary files /dev/null and b/stable/.doctrees/quickstart/quickstart.doctree differ diff --git a/stable/.doctrees/quickstart/scylla-docker.doctree b/stable/.doctrees/quickstart/scylla-docker.doctree new file mode 100644 index 0000000000..9b17ec8893 Binary files /dev/null and b/stable/.doctrees/quickstart/scylla-docker.doctree differ diff --git a/stable/.doctrees/retry-policy/default.doctree b/stable/.doctrees/retry-policy/default.doctree new file mode 100644 index 0000000000..a79fd4f289 Binary files /dev/null and b/stable/.doctrees/retry-policy/default.doctree differ diff --git a/stable/.doctrees/retry-policy/downgrading-consistency.doctree b/stable/.doctrees/retry-policy/downgrading-consistency.doctree new file mode 100644 index 0000000000..1d6a03e055 Binary files /dev/null and b/stable/.doctrees/retry-policy/downgrading-consistency.doctree differ diff --git a/stable/.doctrees/retry-policy/fallthrough.doctree b/stable/.doctrees/retry-policy/fallthrough.doctree new file mode 100644 index 0000000000..7ec39cf35b Binary files /dev/null and b/stable/.doctrees/retry-policy/fallthrough.doctree differ diff --git a/stable/.doctrees/retry-policy/retry-policy.doctree b/stable/.doctrees/retry-policy/retry-policy.doctree new file mode 100644 index 0000000000..2536cfd66b Binary files /dev/null and b/stable/.doctrees/retry-policy/retry-policy.doctree differ diff --git a/stable/.doctrees/schema/schema.doctree b/stable/.doctrees/schema/schema.doctree new file mode 100644 index 0000000000..c163211339 Binary files /dev/null and b/stable/.doctrees/schema/schema.doctree differ diff --git a/stable/.doctrees/speculative-execution/percentile.doctree b/stable/.doctrees/speculative-execution/percentile.doctree new file mode 100644 index 0000000000..2f57819b70 Binary files /dev/null and b/stable/.doctrees/speculative-execution/percentile.doctree differ diff --git a/stable/.doctrees/speculative-execution/simple.doctree b/stable/.doctrees/speculative-execution/simple.doctree new file mode 100644 index 0000000000..18e8a0ff50 Binary files /dev/null and b/stable/.doctrees/speculative-execution/simple.doctree differ diff --git a/stable/.doctrees/speculative-execution/speculative.doctree b/stable/.doctrees/speculative-execution/speculative.doctree new file mode 100644 index 0000000000..484654ef0c Binary files /dev/null and b/stable/.doctrees/speculative-execution/speculative.doctree differ diff --git a/stable/.doctrees/tracing/basic.doctree b/stable/.doctrees/tracing/basic.doctree new file mode 100644 index 0000000000..0116926bca Binary files /dev/null and b/stable/.doctrees/tracing/basic.doctree differ diff --git a/stable/.doctrees/tracing/paged.doctree b/stable/.doctrees/tracing/paged.doctree new file mode 100644 index 0000000000..1825299409 Binary files /dev/null and b/stable/.doctrees/tracing/paged.doctree differ diff --git a/stable/.doctrees/tracing/prepare.doctree b/stable/.doctrees/tracing/prepare.doctree new file mode 100644 index 0000000000..d6bb64eb02 Binary files /dev/null and b/stable/.doctrees/tracing/prepare.doctree differ diff --git a/stable/.doctrees/tracing/query-history.doctree b/stable/.doctrees/tracing/query-history.doctree new file mode 100644 index 0000000000..40dc88e146 Binary files /dev/null and b/stable/.doctrees/tracing/query-history.doctree differ diff --git a/stable/.doctrees/tracing/tracing.doctree b/stable/.doctrees/tracing/tracing.doctree new file mode 100644 index 0000000000..8fbfc26edd Binary files /dev/null and b/stable/.doctrees/tracing/tracing.doctree differ diff --git a/stable/.nojekyll b/stable/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/stable/404.html b/stable/404.html new file mode 100644 index 0000000000..e283e2eea9 --- /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 0000000000..63858016cb --- /dev/null +++ b/stable/CNAME @@ -0,0 +1 @@ +rust-driver.docs.scylladb.com \ No newline at end of file diff --git a/stable/_sources/connecting/authentication.md.txt b/stable/_sources/connecting/authentication.md.txt new file mode 100644 index 0000000000..a18ace127a --- /dev/null +++ b/stable/_sources/connecting/authentication.md.txt @@ -0,0 +1,79 @@ +# Authentication + +Driver supports both authentication by username and password and custom authentication defined by a user. +###### Important: The default authentication credentials are sent in plain text to the server. For this reason, it is highly recommended that this be used in conjunction with client-to-node encryption (SSL), or in a trusted network environment. + +To use the default authentication, specify credentials using the `user` method in `SessionBuilder`: + +```rust +use scylla::{Session, SessionBuilder}; + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .user("myusername", "mypassword") + .build() + .await?; + +``` + ### Custom Authentication + +A custom authentication is defined by implementing the `AuthenticatorSession`. +An `AuthenticatorSession` instance is created per session, so it is also necessary to define a `AuthenticatorProvider` for it. +Finally, to make use of the custom authentication, use the `authenticator_provider` method in `SessionBuilder`: + +```rust +use bytes::{BufMut, BytesMut}; +use async_trait::async_trait; +use scylla::authentication::{AuthError, AuthenticatorProvider, AuthenticatorSession}; + +struct CustomAuthenticator; + +#[async_trait] +impl AuthenticatorSession for CustomAuthenticator { + // to handle an authentication challenge initiated by the server. + // The information contained in the token parameter is authentication protocol specific. + // It may be NULL or empty. + async fn evaluate_challenge( + &mut self, + _token: Option<&[u8]>, + ) -> Result>, AuthError> { + Err("Challenges are not expected".to_string()) + } + + // to handle the success phase of exchange. The token parameters contain information that may be used to finalize the request. + async fn success(&mut self, _token: Option<&[u8]>) -> Result<(), AuthError> { + Ok(()) + } +} + +struct CustomAuthenticatorProvider; + +#[async_trait] +impl AuthenticatorProvider for CustomAuthenticatorProvider { + async fn start_authentication_session( + &self, + _name: &str, + ) -> Result<(Option>, Box), AuthError> { + let mut response = BytesMut::new(); + let cred = "\0cassandra\0cassandra"; + let cred_length = 20; + + response.put_i32(cred_length); + response.put_slice(cred.as_bytes()); + + Ok((Some(response.to_vec()), Box::new(CustomAuthenticator))) + } +} + +async fn authentication_example() -> Result<(), Box> { + use scylla::{Session, SessionBuilder}; + + let _session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .authenticator_provider(Arc::new(CustomAuthenticatorProvider)) + .build() + .await?; + + Ok(()) +} +``` diff --git a/stable/_sources/connecting/compression.md.txt b/stable/_sources/connecting/compression.md.txt new file mode 100644 index 0000000000..4ba755e47c --- /dev/null +++ b/stable/_sources/connecting/compression.md.txt @@ -0,0 +1,30 @@ +# Compression + +By default the driver does not use any compression on connections.\ +It's possible to specify a preferred compression algorithm. \ +The driver will try using it, but if the database doesn't support it, it will fall back to no compression. + +Available compression algorithms: +* Snappy +* LZ4 + +An example enabling `Snappy` compression algorithm: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::Compression; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .compression(Some(Compression::Snappy)) + .build() + .await?; + + Ok(()) +} +``` \ No newline at end of file diff --git a/stable/_sources/connecting/connecting.md.txt b/stable/_sources/connecting/connecting.md.txt new file mode 100644 index 0000000000..04b64be099 --- /dev/null +++ b/stable/_sources/connecting/connecting.md.txt @@ -0,0 +1,110 @@ +# Connecting to the cluster + +Scylla is a distributed database, which means that it operates on multiple nodes running independently. +When creating a `Session` you can specify a few known nodes to which the driver will try connecting: +```rust +use scylla::{Session, SessionBuilder}; +use std::error::Error; +use std::time::Duration; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .known_node("127.0.0.72:4321") + .known_node("localhost:8000") + .connection_timeout(Duration::from_secs(3)) + .cluster_metadata_refresh_interval(Duration::from_secs(10)) + .known_node_addr(SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), + 9000, + )) + .build() + .await?; + + Ok(()) +} +``` + +After successfully connecting to some specified node the driver will fetch topology information about +other nodes in this cluster and connect to them as well. + +## Best practices for using Session + +:::{warning} +Always try to use only a single Session object per apllication because creating them is very expensive! +::: + +The driver maintains its own pool of connections to each node and each connection is capable of handling multiple requests in parallel. Driver will also route requests to nodes / shards that actually own the data (unless the load balancing policy that you use doesn't support it). + +For those reasons, we recommend using one instance of `Session` per application. + +Creating short-lived `Session`'s (e.g. `Session` per request) is strongly discouraged because it will result in great performance penalties because creating a `Session` is a costly process - it requires estabilishing a lot of TCP connections. +Creating many `Session`'s in one application (e.g. `Session` per thread / per Tokio task) is also discouraged, because it wastes resources - as mentioned before, `Session` maintains a connection pool itself and can handle parallel queries, so you would be holding a lot of connections unnecessarily. + +If you need to share `Session` with different threads / Tokio tasks etc. use `Arc` - all methods of `Session` take `&self`, so it doesn't hinder the functionality in any way. + +## Metadata + +The driver refreshes the cluster metadata periodically, which contains information about cluster topology as well as the cluster schema. By default, the driver refreshes the cluster metadata every 60 seconds. +However, you can set the `cluster_metadata_refresh_interval` to a non-negative value to periodically refresh the cluster metadata. This is useful when you do not have unexpected amount of traffic or when you have an extra traffic causing topology to change frequently. + +## Scylla Cloud Serverless + +Scylla Serverless is an elastic and dynamic deployment model. When creating a `Session` you need to +specify the secure connection bundle as follows: + +```rust +use std::path::Path; +use std::error::Error; +use scylla::CloudSessionBuilder; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let session = CloudSessionBuilder::new(Path::new("config_data.yaml")) + .unwrap() + .build() + .await + .unwrap(); + + Ok(()) +} +``` + +Note that the bundle file will be provided after the serverless cluster is created. Here is an example of a +configuration file for a serverless cluster: + +```yaml +datacenters: + datacenter1: + certificateAuthorityData: CERTIFICATE_DATA + server: 127.0.1.1:9142 + nodeDomain: cql.cluster-id.scylla.com + insecureSkipTlsVerify: false +authInfos: + default: + clientCertificateData: CERTIFICATE_DATA + clientKeyData: KEY_DATA + username: scylladb + password: scylladb +contexts: + default: + datacenterName: datacenter1 + authInfoName: default +currentContext: default +``` + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + compression + authentication + tls + +``` \ No newline at end of file diff --git a/stable/_sources/connecting/tls.md.txt b/stable/_sources/connecting/tls.md.txt new file mode 100644 index 0000000000..86f9379955 --- /dev/null +++ b/stable/_sources/connecting/tls.md.txt @@ -0,0 +1,63 @@ +# TLS + +Driver uses the [`openssl`](https://github.com/sfackler/rust-openssl) crate for TLS functionality.\ +It was chosen because [`rustls`](https://github.com/ctz/rustls) doesn't support certificates for ip addresses +(see [issue](https://github.com/briansmith/webpki/issues/54)), which is a common use case for Scylla. + + +### Enabling feature +`openssl` is not a pure Rust library so you need enable a feature and install the proper package. + +To enable the `tls` feature add in `Cargo.toml`: +```toml +scylla = { version = "0.4", features = ["ssl"] } +openssl = "0.10.32" +``` + +Then install the package with `openssl`: +* Debian/Ubuntu: + ```bash + apt install libssl-dev pkg-config + ``` +* Fedora: + ```bash + dnf install openssl-devel + ``` + +* Arch: + ```bash + pacman -S openssl pkg-config + ``` + +### Using TLS +To use tls you will have to create an openssl +[`SslContext`](https://docs.rs/openssl/0.10.33/openssl/ssl/struct.SslContext.html) +and pass it to `SessionBuilder` + +For example, if database certificate is in the file `ca.crt`: +```rust +use scylla::{Session, SessionBuilder}; +use openssl::ssl::{SslContextBuilder, SslMethod, SslVerifyMode}; +use std::path::PathBuf; + +let mut context_builder = SslContextBuilder::new(SslMethod::tls())?; +context_builder.set_ca_file("ca.crt")?; +context_builder.set_verify(SslVerifyMode::PEER); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9142") // The the port is now 9142 + .ssl_context(Some(context_builder.build())) + .build() + .await?; + +``` + +See the full [example](https://github.com/scylladb/scylla-rust-driver/blob/main/examples/tls.rs) for more details diff --git a/stable/_sources/contents.rst.txt b/stable/_sources/contents.rst.txt new file mode 100644 index 0000000000..5bc4a37c9e --- /dev/null +++ b/stable/_sources/contents.rst.txt @@ -0,0 +1,19 @@ +.. toctree:: + :hidden: + :glob: + :titlesonly: + + index + quickstart/quickstart + connecting/connecting + queries/queries + execution-profiles/execution-profiles + data-types/data-types + load-balancing/load-balancing + retry-policy/retry-policy + speculative-execution/speculative + metrics/metrics + migration-guides/migration-guides + logging/logging + tracing/tracing + schema/schema diff --git a/stable/_sources/data-types/blob.md.txt b/stable/_sources/data-types/blob.md.txt new file mode 100644 index 0000000000..fe02634c03 --- /dev/null +++ b/stable/_sources/data-types/blob.md.txt @@ -0,0 +1,21 @@ +# Blob +`Blob` is represented as `Vec` + + +```rust +use scylla::IntoTypedRows; + +// Insert some blob into the table as a Vec +// We can insert it by reference to not move the whole blob +let to_insert: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&to_insert,)) + .await?; + +// Read blobs from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Vec,)>()?; +while let Some((blob_value,)) = iter.next().transpose()? { + println!("{:?}", blob_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/collections.md.txt b/stable/_sources/data-types/collections.md.txt new file mode 100644 index 0000000000..5ef5bf9e7e --- /dev/null +++ b/stable/_sources/data-types/collections.md.txt @@ -0,0 +1,120 @@ +# List, Set, Map + +## List +`List` is represented as `Vec` + +```rust +use scylla::IntoTypedRows; + +// Insert a list of ints into the table +let my_list: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_list,)) + .await?; + +// Read a list of ints from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Vec,)>()?; +while let Some((list_value,)) = iter.next().transpose()? { + println!("{:?}", list_value); +} +``` + +## Set +`Set` is represented as `Vec`, `HashSet` or `BTreeSet`: + +```rust +use scylla::IntoTypedRows; + +// Insert a set of ints into the table +let my_set: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Vec,)>()?; +while let Some((list_value,)) = iter.next().transpose()? { + println!("{:?}", list_value); +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::HashSet; + +// Insert a set of ints into the table +let my_set: HashSet = vec![1, 2, 3, 4, 5].into_iter().collect(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(HashSet,)>()?; +while let Some((list_value,)) = iter.next().transpose()? { + println!("{:?}", list_value); +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::BTreeSet; + +// Insert a set of ints into the table +let my_set: BTreeSet = vec![1, 2, 3, 4, 5].into_iter().collect(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(BTreeSet,)>()?; +while let Some((list_value,)) = iter.next().transpose()? { + println!("{:?}", list_value); +} +``` + +## Map +`Map` is represented as `HashMap` or `BTreeMap` + +```rust +use scylla::IntoTypedRows; +use std::collections::HashMap; + +// Insert a map of text and int into the table +let mut my_map: HashMap = HashMap::new(); +my_map.insert("abcd".to_string(), 16); + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,)) + .await?; + +// Read a map from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(HashMap,)>()?; +while let Some((map_value,)) = iter.next().transpose()? { + println!("{:?}", map_value); +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::BTreeMap; + +// Insert a map of text and int into the table +let mut my_map: BTreeMap = BTreeMap::new(); +my_map.insert("abcd".to_string(), 16); + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,)) + .await?; + +// Read a map from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(BTreeMap,)>()?; +while let Some((map_value,)) = iter.next().transpose()? { + println!("{:?}", map_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/counter.md.txt b/stable/_sources/data-types/counter.md.txt new file mode 100644 index 0000000000..ba32aa5eae --- /dev/null +++ b/stable/_sources/data-types/counter.md.txt @@ -0,0 +1,16 @@ +# Counter +`Counter` is represented as `struct Counter(pub i64)`\ +`Counter` can't be inserted, it can only be read or updated. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::Counter; + +// Read counter from the table +let result = session.query("SELECT c FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Counter,)>()?; +while let Some((counter_value,)) = iter.next().transpose()? { + let counter_int_value: i64 = counter_value.0; + println!("{}", counter_int_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/data-types.md.txt b/stable/_sources/data-types/data-types.md.txt new file mode 100644 index 0000000000..0d9696e765 --- /dev/null +++ b/stable/_sources/data-types/data-types.md.txt @@ -0,0 +1,60 @@ +# Data Types + +The driver maps database data types to matching Rust types +to achieve seamless sending and receiving of CQL values. + +See the following chapters for examples on how to send and receive each data type. + +See [Query values](../queries/values.md) for more information about sending values in queries.\ +See [Query result](../queries/result.md) for more information about reading values from queries + +Database types and their Rust equivalents: +* `Boolean` <----> `bool` +* `Tinyint` <----> `i8` +* `Smallint` <----> `i16` +* `Int` <----> `i32` +* `BigInt` <----> `i64` +* `Float` <----> `f32` +* `Double` <----> `f64` +* `Ascii`, `Text`, `Varchar` <----> `&str`, `String` +* `Counter` <----> `value::Counter` +* `Blob` <----> `Vec` +* `Inet` <----> `std::net::IpAddr` +* `Uuid` <----> `uuid::Uuid` +* `Timeuuid` <----> `value::CqlTimeuuid` +* `Date` <----> `value::CqlDate`, `chrono::NaiveDate`, `time::Date` +* `Time` <----> `value::CqlTime`, `chrono::NaiveTime`, `time::Time` +* `Timestamp` <----> `value::CqlTimestamp`, `chrono::DateTime`, `time::OffsetDateTime` +* `Duration` <----> `value::CqlDuration` +* `Decimal` <----> `value::CqlDecimal`, `bigdecimal::Decimal` +* `Varint` <----> `value::CqlVarint`, `num_bigint::BigInt` (v0.3 and v0.4) +* `List` <----> `Vec` +* `Set` <----> `Vec` +* `Map` <----> `std::collections::HashMap` +* `Tuple` <----> Rust tuples +* `UDT (User defined type)` <----> Custom user structs with macros + + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + primitive + text + counter + blob + inet + uuid + timeuuid + date + time + timestamp + duration + decimal + varint + collections + tuple + udt + +``` diff --git a/stable/_sources/data-types/date.md.txt b/stable/_sources/data-types/date.md.txt new file mode 100644 index 0000000000..ce179bcb5d --- /dev/null +++ b/stable/_sources/data-types/date.md.txt @@ -0,0 +1,91 @@ +# Date + +Depending on feature flags, three different types can be used to interact with date. + +Internally [date](https://docs.scylladb.com/stable/cql/types.html#dates) is represented as number of days since +-5877641-06-23 i.e. 2^31 days before unix epoch. + +## CqlDate + +Without any extra features enabled, only `frame::value::CqlDate` is available. It's an +[`u32`](https://doc.rust-lang.org/std/primitive.u32.html) wrapper and it matches the internal date representation. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlDate; +use scylla::IntoTypedRows; + +// 1970-01-08 +let to_insert = CqlDate((1 << 31) + 7); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read raw Date from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlDate,)>() { + let (date_value,): (CqlDate,) = row?; + } +} +``` + +## chrono::NaiveDate + +If full range is not required and `chrono` feature is enabled, +[`chrono::NaiveDate`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) can be used. +[`chrono::NaiveDate`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) supports dates from +-262145-01-01 to 262143-12-31. + +```rust +use chrono::NaiveDate; +use scylla::IntoTypedRows; + +// 2021-03-24 +let to_insert = NaiveDate::from_ymd_opt(2021, 3, 24).unwrap(); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read NaiveDate from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(NaiveDate,)>()?; +while let Some((date_value,)) = iter.next().transpose()? { + println!("{:?}", date_value); +} +``` + +## time::Date + +Alternatively, `time` feature can be used to enable support of +[`time::Date`](https://docs.rs/time/0.3/time/struct.Date.html). +[`time::Date`](https://docs.rs/time/0.3/time/struct.Date.html)'s value range depends on feature flags, see its +documentation to get more info. + +```rust +use scylla::IntoTypedRows; +use time::{Date, Month}; + +// 2021-03-24 +let to_insert = Date::from_calendar_date(2021, Month::March, 24).unwrap(); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read Date from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Date,)>()?; +while let Some((date_value,)) = iter.next().transpose()? { + println!("{:?}", date_value); +} +``` diff --git a/stable/_sources/data-types/decimal.md.txt b/stable/_sources/data-types/decimal.md.txt new file mode 100644 index 0000000000..fa2f0a9b81 --- /dev/null +++ b/stable/_sources/data-types/decimal.md.txt @@ -0,0 +1,49 @@ +# Decimal +`Decimal` is represented as `value::CqlDecimal` or [`bigdecimal::BigDecimal`](https://docs.rs/bigdecimal/latest/bigdecimal/struct.BigDecimal.html) + +## value::CqlDecimal + +Without any feature flags, the user can interact with `decimal` type by making use of `value::CqlDecimal` which is a very simple wrapper representing the value as signed binary number in big-endian order with a 32-bit scale. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlDecimal; +use std::str::FromStr; + +// Insert a decimal (123.456) into the table +let to_insert: CqlDecimal = + CqlDecimal::from_signed_be_bytes_and_exponent(vec![0x01, 0xE2, 0x40], 3); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a decimal from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(CqlDecimal,)>() { + let (decimal_value,): (CqlDecimal,) = row?; + } +} +``` + +## bigdecimal::BigDecimal + +To make use of `bigdecimal::Bigdecimal` type, user should enable `bigdecimal-04` crate feature. + +```rust +use scylla::IntoTypedRows; +use bigdecimal::BigDecimal; +use std::str::FromStr; + +// Insert a decimal into the table +let to_insert: BigDecimal = BigDecimal::from_str("12345.0")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a decimal from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(BigDecimal,)>()?; +while let Some((decimal_value,)) = iter.next().transpose()? { + println!("{:?}", decimal_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/duration.md.txt b/stable/_sources/data-types/duration.md.txt new file mode 100644 index 0000000000..1d52ffc2ce --- /dev/null +++ b/stable/_sources/data-types/duration.md.txt @@ -0,0 +1,20 @@ +# Duration +`Duration` is represented as [`CqlDuration`](https://docs.rs/scylla/latest/scylla/frame/value/struct.CqlDuration.html)\ + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlDuration; + +// Insert some duration into the table +let to_insert: CqlDuration = CqlDuration { months: 1, days: 2, nanoseconds: 3 }; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read duration from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(CqlDuration,)>()?; +while let Some((duration_value,)) = iter.next().transpose()? { + println!("{:?}", duration_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/inet.md.txt b/stable/_sources/data-types/inet.md.txt new file mode 100644 index 0000000000..51588b5585 --- /dev/null +++ b/stable/_sources/data-types/inet.md.txt @@ -0,0 +1,20 @@ +# Inet +`Inet` is represented as `std::net::IpAddr` + +```rust +use scylla::IntoTypedRows; +use std::net::{IpAddr, Ipv4Addr}; + +// Insert some ip address into the table +let to_insert: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read inet from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(IpAddr,)>()?; +while let Some((inet_value,)) = iter.next().transpose()? { + println!("{:?}", inet_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/primitive.md.txt b/stable/_sources/data-types/primitive.md.txt new file mode 100644 index 0000000000..57fcd7ae9c --- /dev/null +++ b/stable/_sources/data-types/primitive.md.txt @@ -0,0 +1,148 @@ +# Bool, Tinyint, Smallint, Int, Bigint, Float, Double + +### Bool + +`Bool` is represented as rust `bool` + +```rust +use scylla::IntoTypedRows; + +// Insert a bool into the table +let to_insert: bool = true; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a bool from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(bool,)>()?; +while let Some((bool_value,)) = iter.next().transpose()? { + println!("{}", bool_value); +} +``` + +### Tinyint + +`Tinyint` is represented as rust `i8` + +```rust +use scylla::IntoTypedRows; + +// Insert a tinyint into the table +let to_insert: i8 = 123; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a tinyint from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(i8,)>()?; +while let Some((tinyint_value,)) = iter.next().transpose()? { + println!("{:?}", tinyint_value); +} +``` + +### Smallint + +`Smallint` is represented as rust `i16` + +```rust +use scylla::IntoTypedRows; + +// Insert a smallint into the table +let to_insert: i16 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a smallint from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(i16,)>()?; +while let Some((smallint_value,)) = iter.next().transpose()? { + println!("{}", smallint_value); +} +``` + +### Int + +`Int` is represented as rust `i32` + +```rust +use scylla::IntoTypedRows; + +// Insert an int into the table +let to_insert: i32 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read an int from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(i32,)>()?; +while let Some((int_value,)) = iter.next().transpose()? { + println!("{}", int_value); +} +``` + +### Bigint + +`Bigint` is represented as rust `i64` + +```rust +use scylla::IntoTypedRows; + +// Insert a bigint into the table +let to_insert: i64 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a bigint from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(i64,)>()?; +while let Some((bigint_value,)) = iter.next().transpose()? { + println!("{:?}", bigint_value); +} +``` + +### Float + +`Float` is represented as rust `f32` + +```rust +use scylla::IntoTypedRows; + +// Insert a float into the table +let to_insert: f32 = 123.0; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a float from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(f32,)>()?; +while let Some((float_value,)) = iter.next().transpose()? { + println!("{:?}", float_value); +} +``` + +### Double + +`Double` is represented as rust `f64` + +```rust +use scylla::IntoTypedRows; + +// Insert a double into the table +let to_insert: f64 = 12345.0; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a double from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(f64,)>()?; +while let Some((double_value,)) = iter.next().transpose()? { + println!("{:?}", double_value); +} +``` diff --git a/stable/_sources/data-types/text.md.txt b/stable/_sources/data-types/text.md.txt new file mode 100644 index 0000000000..a33d4743ec --- /dev/null +++ b/stable/_sources/data-types/text.md.txt @@ -0,0 +1,25 @@ +# Ascii, Text, Varchar +`Ascii`, `Text` and `Varchar` are represented as `&str` and `String` + +```rust +use scylla::IntoTypedRows; + +// Insert some text into the table as a &str +let to_insert_str: &str = "abcdef"; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_str,)) + .await?; + +// Insert some text into the table as a String +let to_insert_string: String = "abcdef".to_string(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_string,)) + .await?; + +// Read ascii/text/varchar from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(String,)>()?; +while let Some((text_value,)) = iter.next().transpose()? { + println!("{}", text_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/time.md.txt b/stable/_sources/data-types/time.md.txt new file mode 100644 index 0000000000..cd005c97a6 --- /dev/null +++ b/stable/_sources/data-types/time.md.txt @@ -0,0 +1,89 @@ +# Time + +Depending on feature flags used, three different types can be used to interact with time. + +Internally [time](https://docs.scylladb.com/stable/cql/types.html#times) is represented as number of nanoseconds since +midnight. It can't be negative or exceed `86399999999999` (23:59:59.999999999). + +## CqlTime + +Without any extra features enabled, only `frame::value::CqlTime` is available. It's an +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) wrapper and it matches the internal time representation. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlTime; +use scylla::IntoTypedRows; + +// 64 seconds since midnight +let to_insert = CqlTime(64 * 1_000_000_000); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlTime,)>() { + let (time_value,): (CqlTime,) = row?; + } +} +``` + +## chrono::NaiveTime + +If `chrono` feature is enabled, [`chrono::NaiveTime`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) +can be used to interact with the database. Although chrono can represent leap seconds, they are not supported. +Attempts to convert [`chrono::NaiveTime`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) with leap +second to `CqlTime` or write it to the database will return an error. + +```rust +use chrono::NaiveTime; +use scylla::IntoTypedRows; + +// 01:02:03.456,789,012 +let to_insert = NaiveTime::from_hms_nano_opt(1, 2, 3, 456_789_012); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(NaiveTime,)>()?; +while let Some((time_value,)) = iter.next().transpose()? { + println!("{:?}", time_value); +} +``` + +## time::Time + +If `time` feature is enabled, [`time::Time`](https://docs.rs/time/0.3/time/struct.Time.html) can be used to interact +with the database. + +```rust +use scylla::IntoTypedRows; +use time::Time; + +// 01:02:03.456,789,012 +let to_insert = Time::from_hms_nano(1, 2, 3, 456_789_012).unwrap(); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Time,)>()?; +while let Some((time_value,)) = iter.next().transpose()? { + println!("{:?}", time_value); +} +``` diff --git a/stable/_sources/data-types/timestamp.md.txt b/stable/_sources/data-types/timestamp.md.txt new file mode 100644 index 0000000000..8157751552 --- /dev/null +++ b/stable/_sources/data-types/timestamp.md.txt @@ -0,0 +1,101 @@ +# Timestamp + +Depending on feature flags, three different types can be used to interact with timestamps. + +Internally [timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) is represented as +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) describing number of milliseconds since unix epoch. + +## CqlTimestamp + +Without any extra features enabled, only `frame::value::CqlTimestamp` is available. It's an +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) wrapper and it matches the internal time representation. It's +the only type that supports full range of values that database accepts. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlTimestamp; +use scylla::IntoTypedRows; + +// 64 seconds since unix epoch, 1970-01-01 00:01:04 +let to_insert = CqlTimestamp(64 * 1000); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlTimestamp,)>() { + let (timestamp_value,): (CqlTimestamp,) = row?; + } +} +``` + +## chrono::DateTime + +If full value range is not required, `chrono` feature can be used to enable support of +[`chrono::DateTime`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html). All values are expected to be converted +to UTC timezone explicitly, as [timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) doesn't store +timezone information. Any precision finer than 1ms will be lost. + +```rust +use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc}; +use scylla::IntoTypedRows; + +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123 +let to_insert = NaiveDateTime::new( + NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(), + NaiveTime::from_hms_milli_opt(0, 1, 4, 123).unwrap(), +) +.and_utc(); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(DateTime,)>()?; +while let Some((timestamp_value,)) = iter.next().transpose()? { + println!("{:?}", timestamp_value); +} +``` + +## time::OffsetDateTime + +Alternatively, `time` feature can be used to enable support of +[`time::OffsetDateTime`](https://docs.rs/time/0.3/time/struct.OffsetDateTime.html). As +[timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) doesn't support timezone information, time will +be corrected to UTC and timezone info will be erased on write. On read, UTC timestamp is returned. Any precision finer +than 1ms will also be lost. + +```rust +use scylla::IntoTypedRows; +use time::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time}; + +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123 +let to_insert = PrimitiveDateTime::new( + Date::from_calendar_date(1970, Month::January, 1).unwrap(), + Time::from_hms_milli(0, 1, 4, 123).unwrap(), +) +.assume_utc(); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(OffsetDateTime,)>()?; +while let Some((timestamp_value,)) = iter.next().transpose()? { + println!("{:?}", timestamp_value); +} +``` diff --git a/stable/_sources/data-types/timeuuid.md.txt b/stable/_sources/data-types/timeuuid.md.txt new file mode 100644 index 0000000000..147836543f --- /dev/null +++ b/stable/_sources/data-types/timeuuid.md.txt @@ -0,0 +1,23 @@ +# Timeuuid + +`Timeuuid` is represented as `value::CqlTimeuuid`. +`value::CqlTimeuuid` is a wrapper for `uuid::Uuid` with custom ordering logic +which follows Scylla/Cassandra semantics. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlTimeuuid; + +// Insert some timeuuid into the table +let to_insert: CqlTimeuuid = CqlTimeuuid::from_str("8e14e760-7fa8-11eb-bc66-000000000001")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timeuuid from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(CqlTimeuuid,)>() { + let (timeuuid_value,): (CqlTimeuuid,) = row?; + } +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/tuple.md.txt b/stable/_sources/data-types/tuple.md.txt new file mode 100644 index 0000000000..8403d6b6b8 --- /dev/null +++ b/stable/_sources/data-types/tuple.md.txt @@ -0,0 +1,22 @@ +# Tuple + +`Tuple` is represented as rust tuples of max 16 elements. + +```rust +use scylla::IntoTypedRows; + +// Insert a tuple of int and string into the table +let to_insert: (i32, String) = (1, "abc".to_string()); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a tuple of int and string from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<((i32, String),)>()?; +while let Some((tuple_value,)) = iter.next().transpose()? { + let int_value: i32 = tuple_value.0; + let string_value: String = tuple_value.1; + println!("({}, {})", int_value, string_value); +} +``` diff --git a/stable/_sources/data-types/udt.md.txt b/stable/_sources/data-types/udt.md.txt new file mode 100644 index 0000000000..4660d7f982 --- /dev/null +++ b/stable/_sources/data-types/udt.md.txt @@ -0,0 +1,71 @@ +# User defined types +Scylla allows users to define their own data types with named fields (See [the official documentation](https://opensource.docs.scylladb.com/stable/cql/types.html#user-defined-types))\ +To use user defined types in the driver, you can create a corresponding struct in Rust, and use it to read and write UDT values. + + +For example let's say `my_type` was created using this query: +```sql +CREATE TYPE ks.my_type (int_val int, text_val text) +``` + +To use this type in the driver, create a matching struct and derive: +- `SerializeCql`: in order to be able to use this struct in query parameters. \ + This macro requires fields of UDT and struct to have matching names, but the order + of the fields is not required to be the same. \ + Note: you can use different name using `rename` attribute - see `SerializeCql` macro documentation. +- `FromUserType`: in order to be able to use this struct in query results. \ + This macro requires fields of UDT and struct to be in the same *ORDER*. \ + This mismatch between `SerializeCql` and `FromUserType` requirements is a temporary situation - in the future `FromUserType` (or the macro that replaces it) will also require matching names. + +```rust +use scylla::macros::{FromUserType, SerializeCql}; + +// Define a custom struct that matches the User Defined Type created earlier. +// Fields must be in the same order as they are in the database and also +// have the same names. +// Wrapping a field in Option will gracefully handle null field values. +#[derive(Debug, FromUserType, SerializeCql)] +struct MyType { + int_val: i32, + text_val: Option, +} +``` + +> ***Important***\ +> For deserialization, fields in the Rust struct must be defined in the same order as they are in the database. +> When receiving values, the driver will (de)serialize fields one after another, without looking at field names. + +> ***Important***\ +> For serialization, by default fields in the Rust struct must be defined with the same names as they are in the database. +> The driver will serialize the fields in the order defined by the UDT, matching Rust fields by name. +> You can change this behaviour using macro attributes, see `SerializeCql` macro documentation for more information. + +Now it can be sent and received just like any other CQL value: +```rust +use scylla::IntoTypedRows; +use scylla::macros::{FromUserType, SerializeCql}; +use scylla::cql_to_rust::FromCqlVal; + +#[derive(Debug, FromUserType, SerializeCql)] +struct MyType { + int_val: i32, + text_val: Option, +} + +// Insert my_type into the table +let to_insert = MyType { + int_val: 17, + text_val: Some("Some string".to_string()), +}; + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read MyType from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(MyType,)>()?; +while let Some((my_type_value,)) = iter.next().transpose()? { + println!("{:?}", my_type_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/uuid.md.txt b/stable/_sources/data-types/uuid.md.txt new file mode 100644 index 0000000000..5da0606307 --- /dev/null +++ b/stable/_sources/data-types/uuid.md.txt @@ -0,0 +1,21 @@ +# Uuid + +`Uuid` is represented as `uuid::Uuid`. + +```rust +use scylla::IntoTypedRows; +use uuid::Uuid; + +// Insert some uuid into the table +let to_insert: Uuid = Uuid::parse_str("8e14e760-7fa8-11eb-bc66-000000000001")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read uuid from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Uuid,)>()?; +while let Some((uuid_value,)) = iter.next().transpose()? { + println!("{:?}", uuid_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/data-types/varint.md.txt b/stable/_sources/data-types/varint.md.txt new file mode 100644 index 0000000000..dd71139721 --- /dev/null +++ b/stable/_sources/data-types/varint.md.txt @@ -0,0 +1,32 @@ +# Varint +`Varint` is represented as `value::CqlVarint` or [`num_bigint::BigInt`](https://docs.rs/num-bigint/0.4.0/num_bigint/struct.BigInt.html). + +## num_bigint::BigInt + +To make use of `num_bigint::BigInt` type, user should enable one of the available feature flags (`num-bigint-03` or `num-bigint-04`). They enable support for `num_bigint::BigInt` v0.3 and v0.4 accordingly. + +## value::CqlVarint + +Without any feature flags, the user can interact with `Varint` type by making use of `value::CqlVarint` which +is a very simple wrapper representing the value as signed binary number in big-endian order. + +## Example + +```rust +use scylla::IntoTypedRows; +use num_bigint::BigInt; +use std::str::FromStr; + +// Insert a varint into the table +let to_insert: BigInt = BigInt::from_str("12345")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a varint from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(BigInt,)>()?; +while let Some((varint_value,)) = iter.next().transpose()? { + println!("{:?}", varint_value); +} +``` \ No newline at end of file diff --git a/stable/_sources/execution-profiles/create-and-use.md.txt b/stable/_sources/execution-profiles/create-and-use.md.txt new file mode 100644 index 0000000000..e33d5d2a26 --- /dev/null +++ b/stable/_sources/execution-profiles/create-and-use.md.txt @@ -0,0 +1,61 @@ +# Creating a profile and setting it + +### Example +To create an `ExecutionProfile` and attach it as default for `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::LocalOne) + .request_timeout(None) // no request timeout + .build(); + +let handle = profile.into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +### Example +To create an `ExecutionProfile` and attach it to a `Query`: +```rust +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::All) + .request_timeout(Some(Duration::from_secs(30))) + .build(); + +let handle = profile.into_handle(); + +let mut query1 = Query::from("SELECT * FROM ks.table"); +query1.set_execution_profile_handle(Some(handle.clone())); + +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?"); +query2.set_execution_profile_handle(Some(handle)); +``` + +### Example +To create an `ExecutionProfile` based on another profile: +```rust +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let base_profile = ExecutionProfile::builder() + .request_timeout(Some(Duration::from_secs(30))) + .build(); + +let profile = base_profile.to_builder() + .consistency(Consistency::All) + .build(); + +``` \ No newline at end of file diff --git a/stable/_sources/execution-profiles/execution-profiles.md.txt b/stable/_sources/execution-profiles/execution-profiles.md.txt new file mode 100644 index 0000000000..6f36726aff --- /dev/null +++ b/stable/_sources/execution-profiles/execution-profiles.md.txt @@ -0,0 +1,26 @@ +# Execution profiles + +Execution profiles are a way to group various query execution configuration options together. Profiles can be created to represent different workloads, which can be run conveniently on a single session. + +The settings that an execution profile encapsulates are [as follows](maximal-example.md): +* consistency +* serial consistency +* request timeout +* load balancing policy +* retry policy +* speculative execution policy + +There are two classes of objects related to execution profiles: `ExecutionProfile` and `ExecutionProfileHandle`. The former is simply an immutable set of the settings. The latter is a handle that at particular moment points to some `ExecutionProfile` (but during its lifetime, it can change the profile it points at). Handles are assigned to `Sessions` and `Statements`.\ +\ +At any moment, handles [can be remapped](remap.md) to point to another `ExecutionProfile`. This allows convenient switching between workloads for all `Sessions` and/or `Statements` that, for instance, share common characteristics. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + create-and-use + maximal-example + priority + remap +``` \ No newline at end of file diff --git a/stable/_sources/execution-profiles/maximal-example.md.txt b/stable/_sources/execution-profiles/maximal-example.md.txt new file mode 100644 index 0000000000..b784786574 --- /dev/null +++ b/stable/_sources/execution-profiles/maximal-example.md.txt @@ -0,0 +1,35 @@ +# All options supported by a profile + +### Example +`ExecutionProfile` supports all the following options: +```rust +use scylla::query::Query; +use scylla::speculative_execution::SimpleSpeculativeExecutionPolicy; +use scylla::statement::{Consistency, SerialConsistency}; +use scylla::transport::ExecutionProfile; +use scylla::transport::load_balancing::DefaultPolicy; +use scylla::transport::retry_policy::FallthroughRetryPolicy; +use std::{sync::Arc, time::Duration}; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::All) + .serial_consistency(Some(SerialConsistency::Serial)) + .request_timeout(Some(Duration::from_secs(30))) + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .load_balancing_policy(Arc::new(DefaultPolicy::default())) + .speculative_execution_policy( + Some( + Arc::new( + SimpleSpeculativeExecutionPolicy { + max_retry_count: 3, + retry_interval: Duration::from_millis(100), + } + ) + ) + ) + .build(); + +let mut query = Query::from("SELECT * FROM ks.table"); +query.set_execution_profile_handle(Some(profile.into_handle())); + +``` \ No newline at end of file diff --git a/stable/_sources/execution-profiles/priority.md.txt b/stable/_sources/execution-profiles/priority.md.txt new file mode 100644 index 0000000000..246c90fa24 --- /dev/null +++ b/stable/_sources/execution-profiles/priority.md.txt @@ -0,0 +1,48 @@ +# Priorities of execution settings + +You always have a default execution profile set for the `Session`, either the default one or overridden upon `Session` creation. Moreover, you can set a profile for specific statements, in which case the statement's profile has higher priority. Some options are also available for specific statements to be set directly on them, such as request timeout and consistency. In such case, the directly set options are preferred over those specified in execution profiles. + +> **Recap**\ +> Priorities are as follows:\ +> `Session`'s default profile < Statement's profile < options set directly on a Statement + + +### Example +Priorities of execution profiles and directly set options: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let session_profile = ExecutionProfile::builder() + .consistency(Consistency::One) + .build(); + +let query_profile = ExecutionProfile::builder() + .consistency(Consistency::Two) + .build(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(session_profile.into_handle()) + .build() + .await?; + +let mut query = Query::from("SELECT * FROM ks.table"); + +// Query is not assigned any specific profile, so session's profile is applied. +// Therefore, the query will be executed with Consistency::One. +session.query(query.clone(), ()).await?; + +query.set_execution_profile_handle(Some(query_profile.into_handle())); +// Query's profile is applied. +// Therefore, the query will be executed with Consistency::Two. +session.query(query.clone(), ()).await?; + +query.set_consistency(Consistency::Three); +// An option is set directly on the query. +// Therefore, the query will be executed with Consistency::Three. +session.query(query, ()).await?; + +``` \ No newline at end of file diff --git a/stable/_sources/execution-profiles/remap.md.txt b/stable/_sources/execution-profiles/remap.md.txt new file mode 100644 index 0000000000..470ebaefe7 --- /dev/null +++ b/stable/_sources/execution-profiles/remap.md.txt @@ -0,0 +1,69 @@ +# Remapping execution profile handles + +`ExecutionProfileHandle`s can be remapped to another `ExecutionProfile`, and the change affects all sessions and statements that have been assigned that handle. This enables quick workload switches. + +Example mapping: +* session1 -> handle1 -> profile1 +* statement1 -> handle1 -> profile1 +* statement2 -> handle2 -> profile2 + +We can now remap handle2 to profile1, so that the mapping for statement2 becomes as follows: +* statement2 -> handle2 -> profile1 + +We can also change statement1's handle to handle2, and remap handle1 to profile2, yielding: +* session1 -> handle1 -> profile2 +* statement1 -> handle2 -> profile1 +* statement2 -> handle2 -> profile1 + +As you can see, profiles are a powerful and convenient way to define and modify your workloads. + +### Example +Below, the remaps described above are followed in code. +```rust +use scylla::{Session, SessionBuilder}; +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let profile1 = ExecutionProfile::builder() + .consistency(Consistency::One) + .build(); + +let profile2 = ExecutionProfile::builder() + .consistency(Consistency::Two) + .build(); + +let mut handle1 = profile1.clone().into_handle(); +let mut handle2 = profile2.clone().into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle1.clone()) + .build() + .await?; + +let mut query1 = Query::from("SELECT * FROM ks.table"); +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?"); + +query1.set_execution_profile_handle(Some(handle1.clone())); +query2.set_execution_profile_handle(Some(handle2.clone())); + +// session1 -> handle1 -> profile1 +// query1 -> handle1 -> profile1 +// query2 -> handle2 -> profile2 + +// We can now remap handle2 to profile1: +handle2.map_to_another_profile(profile1); +// ...so that the mapping for query2 becomes as follows: +// query2 -> handle2 -> profile1 + +// We can also change query1's handle to handle2: +query1.set_execution_profile_handle(Some(handle2.clone())); +// ...and remap handle1 to profile2: +handle1.map_to_another_profile(profile2); +// ...yielding: +// session1 -> handle1 -> profile2 +// query1 -> handle2 -> profile1 +// query2 -> handle2 -> profile1 + +``` \ No newline at end of file diff --git a/stable/_sources/index.md.txt b/stable/_sources/index.md.txt new file mode 100644 index 0000000000..d2a6b79313 --- /dev/null +++ b/stable/_sources/index.md.txt @@ -0,0 +1,26 @@ +# Scylla Rust Driver +This book contains documentation for [scylla-rust-driver](https://github.com/scylladb/scylla-rust-driver) - a driver +for the [Scylla](https://scylladb.com) database written in Rust. +Although optimized for Scylla, the driver is also compatible with [Apache Cassandra®](https://cassandra.apache.org/). + +### Other documentation +* [Examples](https://github.com/scylladb/scylla-rust-driver/tree/main/examples) +* [Rust and Scylla lesson](https://university.scylladb.com/courses/using-scylla-drivers/lessons/rust-and-scylla-2/) on Scylla University +* [API documentation](https://docs.rs/scylla) +* [Scylla documentation](https://docs.scylladb.com) +* [Cassandra® documentation](https://cassandra.apache.org/doc/latest/) + + +## Contents +* [Quick start](quickstart/quickstart.md) - Setting up a Rust project using `scylla-rust-driver` and running a few queries +* [Migration guides](migration-guides/migration-guides.md) - How to update the code that used an older version of this driver +* [Connecting to the cluster](connecting/connecting.md) - Configuring a connection to scylla cluster +* [Making queries](queries/queries.md) - Making different types of queries (simple, prepared, batch, paged) +* [Execution profiles](execution-profiles/execution-profiles.md) - Grouping query execution configuration options together and switching them all at once +* [Data Types](data-types/data-types.md) - How to use various column data types +* [Load balancing](load-balancing/load-balancing.md) - Load balancing configuration +* [Retry policy configuration](retry-policy/retry-policy.md) - What to do when a query fails, query idempotence +* [Driver metrics](metrics/metrics.md) - Statistics about the driver - number of queries, latency etc. +* [Logging](logging/logging.md) - Viewing and integrating logs produced by the driver +* [Query tracing](tracing/tracing.md) - Tracing query execution +* [Database schema](schema/schema.md) - Fetching and inspecting database schema diff --git a/stable/_sources/load-balancing/default-policy.md.txt b/stable/_sources/load-balancing/default-policy.md.txt new file mode 100644 index 0000000000..c1ad0ee2bf --- /dev/null +++ b/stable/_sources/load-balancing/default-policy.md.txt @@ -0,0 +1,167 @@ +# DefaultPolicy + +`DefaultPolicy` is the default load balancing policy in Scylla Rust Driver. It +can be configured to be datacenter-aware and token-aware. Datacenter failover +for queries with non-local consistency mode is also supported. + +## Creating a DefaultPolicy + +`DefaultPolicy` can be created only using `DefaultPolicyBuilder`. The +`builder()` method of `DefaultPolicy` returns a new instance of +`DefaultPolicyBuilder` with the following default values: + +- `preferences`: no particular datacenter/rack preference +- `is_token_aware`: `true` +- `permit_dc_failover`: `false` +- `latency_awareness`: `None` + +You can use the builder methods to configure the desired settings and create a +`DefaultPolicy` instance: + +```rust +use scylla::load_balancing::DefaultPolicy; + +let default_policy = DefaultPolicy::builder() + .prefer_datacenter_and_rack("dc1".to_string(), "rack1".to_string()) + .token_aware(true) + .permit_dc_failover(true) + .build(); +``` + +### Semantics of `DefaultPolicy` + +#### Preferences + +The `preferences` field in `DefaultPolicy` allows the load balancing +policy to prioritize nodes based on their location. It has three modes: + +- no preference +- preferred datacenter +- preferred datacenter and rack + +When a datacenter `"my_dc"` is preferred, the policy will treat nodes in `"my_dc"` +as "local" nodes, and nodes in other datacenters as "remote" nodes. This affects +the order in which nodes are returned by the policy when selecting nodes for +read or write operations. If no datacenter is preferred, the policy will treat +all nodes as local nodes. + +`preferences` allow the load balancing policy to prioritize nodes based on their +availability zones (racks) in the preferred datacenter, too. When a datacenter +and a rack are preferred, the policy will first return replicas in the local rack +in the preferred datacenter, and then the other replicas in the datacenter +(followed by remote replicas). After replicas, the other node will be ordered +similarly, too (local rack nodes, local datacenter nodes, remote nodes). + +When datacenter failover is disabled (`permit_dc_failover` is set to +false), the default policy will only include local nodes in load balancing +plans. Remote nodes will be excluded, even if they are alive and available to +serve requests. + +#### Datacenter Failover + +In the event of a datacenter outage or network failure, the nodes in that +datacenter may become unavailable, and clients may no longer be able to access +the data stored on those nodes. To address this, the `DefaultPolicy` supports +datacenter failover, which allows to route requests to nodes in other datacenters +if the local nodes are unavailable. + +Datacenter failover can be enabled in `DefaultPolicy` by `permit_dc_failover` +setting in the builder. When this flag is set, the policy will prefer to return +alive remote replicas if datacenter failover is permitted and possible due to +consistency constraints. + +#### Token awareness + +Token awareness refers to a mechanism by which the driver is aware of the token +range assigned to each node in the cluster. Tokens are assigned to nodes to +partition the data and distribute it across the cluster. + +When a user wants to read or write data, the driver can use token awareness to +route the request to the correct node based on the token range of the data +being accessed. This can help to minimize network traffic and improve +performance by ensuring that the data is accessed locally as much as possible. + +In the case of `DefaultPolicy`, token awareness is enabled by default, meaning +that the policy will prefer to return alive local replicas if the token is +available. This means that if the client is requesting data that falls within +the token range of a particular node, the policy will try to route the request +to that node first, assuming it is alive and responsive. + +Token awareness can significantly improve the performance and scalability of +applications built on Scylla. By using token awareness, users can ensure that +data is accessed locally as much as possible, reducing network overhead and +improving throughput. + +Please note that for token awareness to be applied, a statement must be +prepared before being executed. + +### Latency awareness + +Latency awareness is a mechanism that penalises nodes whose measured recent +average latency classifies it as falling behind the others. + +Every `update_rate` the global minimum average latency is computed, +and all nodes whose average latency is worse than `exclusion_threshold` +times the global minimum average latency become penalised for +`retry_period`. Penalisation involves putting those nodes at the very end +of the query plan. As it is often not truly beneficial to prefer +faster non-replica than replicas lagging behind the non-replicas, +this mechanism may as well worsen latencies and/or throughput. + +> **Warning** +> +> Using latency awareness is **NOT** recommended, unless prior +>benchmarks prove its beneficial impact on the specific workload's +>performance. Use with caution. + +### Creating a latency aware DefaultPolicy + +```rust +use scylla::load_balancing::{ + LatencyAwarenessBuilder, DefaultPolicy +}; +use std::time::Duration; + +let latency_awareness_builder = LatencyAwarenessBuilder::new() + .exclusion_threshold(3.) + .update_rate(Duration::from_secs(3)) + .retry_period(Duration::from_secs(30)) + .minimum_measurements(200); + +let policy = DefaultPolicy::builder() + // Here further customisation is, of course, possible. + // e.g.: .prefer_datacenter(...) + .latency_awareness(latency_awareness_builder) + .build(); +``` + +```rust +use scylla::load_balancing::DefaultPolicy; + +let default_policy = DefaultPolicy::builder() + .prefer_datacenter("dc1".to_string()) + .token_aware(true) + .permit_dc_failover(true) + .build(); +``` + +### Node order in produced plans + +The DefaultPolicy prefers to return nodes in the following order: + +1. Alive local replicas (if token is available & token awareness is enabled) +2. Alive remote replicas (if datacenter failover is permitted & possible due to consistency constraints) +3. Alive local nodes +4. Alive remote nodes (if datacenter failover is permitted & possible due to consistency constraints) +5. Enabled down nodes +And only if latency awareness is enabled: +6. Penalised: alive local replicas, alive remote replicas, ... (in order as above). + +If no preferred datacenter is specified, all nodes are treated as local ones. + +Replicas in the same priority groups are shuffled[^1]. Non-replicas are randomly +rotated (similarly to a round robin with a random index). + +[^1]: There is an optimisation implemented for LWT requests that routes them +to the replicas in the ring order (as it prevents contention due to Paxos conflicts), so replicas in that case are not shuffled in groups at all. +In order for the optimisation to be applied, LWT statements must be prepared before. diff --git a/stable/_sources/load-balancing/load-balancing.md.txt b/stable/_sources/load-balancing/load-balancing.md.txt new file mode 100644 index 0000000000..a6b9a28e1a --- /dev/null +++ b/stable/_sources/load-balancing/load-balancing.md.txt @@ -0,0 +1,120 @@ +# Load balancing + +## Introduction + +The driver uses a load balancing policy to determine which node(s) and shard(s) +to contact when executing a query. Load balancing policies implement the +`LoadBalancingPolicy` trait, which contains methods to generate a load +balancing plan based on the query information and the state of the cluster. + +Load balancing policies do not influence to which nodes connections are +being opened. For a node connection blacklist configuration refer to +`scylla::transport::host_filter::HostFilter`, which can be set session-wide +using `SessionBuilder::host_filter` method. + +In this chapter, "target" will refer to a pair ``. + +## Plan + +When a query is prepared to be sent to the database, the load balancing policy +constructs a load balancing plan. This plan is essentially a list of targets to +which the driver will try to send the query. The first elements of the plan are +the targets which are the best to contact (e.g. they might be replicas for the +requested data or have the best latency). + +## Policy + +The Scylla/Cassandra driver provides a default load balancing policy (see +[Default Policy](default-policy.md) for details), but you can +also implement your own custom policies that better suit your specific use +case. To use a custom policy, you simply need to implement the +`LoadBalancingPolicy` trait and pass an instance of your custom policy to the +used execution profile. + +Our recommendation is to use [`Default Policy`](default-policy.md) with token- +awareness enabled and latency-awareness disabled. + +## Configuration + +Load balancing policies can be configured via execution profiles. In the code +sample provided, a new execution profile is created using +`ExecutionProfile::builder()`, and the load balancing policy is set to the +`DefaultPolicy` using `.load_balancing_policy(policy)`. + +The newly created execution profile is then converted to a handle using +`.into_handle()`, and passed as the default execution profile to the +`SessionBuilder` using `.default_execution_profile_handle(handle)`. + +```rust +use scylla::SessionBuilder; +use scylla::load_balancing::DefaultPolicy; +use scylla::transport::ExecutionProfile; +use scylla::transport::session::Session; +use std::sync::Arc; + +let policy = Arc::new(DefaultPolicy::default()); + +let profile = ExecutionProfile::builder() + .load_balancing_policy(policy) + .build(); +let handle = profile.into_handle(); + +let session: Session = SessionBuilder::new() + .known_node(&uri) + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +In addition to being able to configure load balancing policies through +execution profiles at the session level, the driver also allow for setting +execution profile handles on a per-query basis. This means that for each query, +a specific execution profile can be selected with a customized load balancing +settings. + +## `LoadBalancingPolicy` trait + +### `pick` and `fallback`: + +Most queries are sent successfully on the first try. In such cases, only the +first element of the load balancing plan is needed, so it's usually unnecessary +to compute entire load balancing plan. To optimize this common case, the +`LoadBalancingPolicy` trait provides two methods: `pick` and `fallback`. + +`pick` returns the first target to contact for a given query, which is usually +the best based on a particular load balancing policy. + +`fallback`, returns an iterator that provides the rest of the targets in the +load balancing plan. `fallback` is called when using the initial picked +target fails (or when executing speculatively) or when `pick` returned `None`. + +It's possible for the `fallback` method to include the same target that was +returned by the `pick` method. In such cases, the query execution layer filters +out the picked target from the iterator returned by `fallback`. + +### `on_query_success` and `on_query_failure`: + +The `on_query_success` and `on_query_failure` methods are useful for load +balancing policies because they provide feedback on the performance and health +of the nodes in the cluster. + +When a query is successfully executed, the `on_query_success` method is called +and can be used by the load balancing policy to update its internal state. For +example, a policy might use the latency of the successful query to update its +latency statistics for each node in the cluster. This information can be used +to make decisions about which nodes to contact in the future. + +On the other hand, when a query fails to execute, the `on_query_failure` method +is called and provides information about the failure. The error message +returned by Cassandra can help determine the cause of the failure, such as a +node being down or overloaded. The load balancing policy can use this +information to update its internal state and avoid contacting the same node +again until it's recovered. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + default-policy +``` diff --git a/stable/_sources/logging/logging.md.txt b/stable/_sources/logging/logging.md.txt new file mode 100644 index 0000000000..5b129f4cdc --- /dev/null +++ b/stable/_sources/logging/logging.md.txt @@ -0,0 +1,42 @@ +# Logging + +The driver uses the [tracing](https://github.com/tokio-rs/tracing) crate for all logs.\ +To view the logs you have to create a `tracing` subscriber to which all logs will be written. + +To just print the logs you can use the default subscriber: +```rust +use tracing::info; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Install global collector configured based on RUST_LOG env var + // This collector will receive logs from the driver + tracing_subscriber::fmt::init(); + + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + info!("Connecting to {}", uri); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + session + .query( + "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \ + {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}", + &[], + ) + .await?; + + // This query should generate a warning message + session.query("USE ks", &[]).await?; + + Ok(()) +} +``` + +To start this example execute: +```shell +RUST_LOG=info cargo run +``` + +The full [example](https://github.com/scylladb/scylla-rust-driver/tree/main/examples/logging.rs) is available in the `examples` folder \ No newline at end of file diff --git a/stable/_sources/metrics/metrics.md.txt b/stable/_sources/metrics/metrics.md.txt new file mode 100644 index 0000000000..7fb831a504 --- /dev/null +++ b/stable/_sources/metrics/metrics.md.txt @@ -0,0 +1,28 @@ +# Driver metrics + +During operation the driver collects various metrics. + +They can be accessed at any moment using `Session::get_metrics()` + +### Collected metrics: +* Query latencies +* Total number of nonpaged queries +* Number of errors during nonpaged queries +* Total number of paged queries +* Number of errors during paged queries +* Number of retries + +### Example +```rust +let metrics = session.get_metrics(); + +println!("Queries requested: {}", metrics.get_queries_num()); +println!("Iter queries requested: {}", metrics.get_queries_iter_num()); +println!("Errors occurred: {}", metrics.get_errors_num()); +println!("Iter errors occurred: {}", metrics.get_errors_iter_num()); +println!("Average latency: {}", metrics.get_latency_avg_ms().unwrap()); +println!( + "99.9 latency percentile: {}", + metrics.get_latency_percentile_ms(99.9).unwrap() +); +``` \ No newline at end of file diff --git a/stable/_sources/migration-guides/0.11-serialization.md.txt b/stable/_sources/migration-guides/0.11-serialization.md.txt new file mode 100644 index 0000000000..429a0168cf --- /dev/null +++ b/stable/_sources/migration-guides/0.11-serialization.md.txt @@ -0,0 +1,101 @@ +# Adjusting code to changes in serialization API introduced in 0.11 + +## Background + +When executing a statement through the CQL protocol, values for the bind markers are sent in a serialized, untyped form. In order to implement a safer and more robust interface, drivers can use the information returned after preparing a statement to check the type of data provided by the user against the actual types of the bind markers. + +Before 0.11, the driver couldn't do this kind of type checking. For example, in the case of non-batch queries, the only information about the user data it has is that it implements `ValueList` - defined as follows: + +```rust + +pub trait ValueList { + fn serialized(&self) -> SerializedResult<'_>; + fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError>; +} +``` + +The driver would naively serialize the data and hope that the user took care to send correct types of values. Failing to do so would, in the best case, fail on the DB-side validation; in the worst case, the data in its raw form may be reinterpreted as another type in an unintended manner. + +Another problem is that the information from the prepared statement response is required to robustly serialize user defined types, as UDTs require their fields to be serialized in the same order as they are defined in the database schema. The `IntoUserType` macro which implements Rust struct -> UDT serialization just expects that the order of the Rust struct fields matches the schema, but ensuring this can be very cumbersome for the users. + +In version 0.11, a new set of traits is introduced and the old ones are deprecated. The new traits receive more information during serialization such as names of the column/bind markers and their types, which allows to fix the issues mentioned in the previous section. + +## Old vs. new + +Both the old and the new APIs are based on three core traits: + +- `Value` - called `SerializeCql` in the new API. A type that can serialize itself to a single CQL value. For example, `i32` serializes itself into a representation that is compatible with the CQL `int` type. +- `ValueList` - called `SerializeRow` in the new API. A type that can serialize itself as a list of values for a CQL statement. For example, a `(i32, &str)` produces a list of two values which can be used in a query with two bind markers, e.g. `SELECT * FROM table WHERE pk = ? AND ck = ?`. Optionally, values in the produced list may be associated with names which is useful when using it with a query with named bind markers, e.g. `SELECT * FROM table WHERE pk = :pk AND ck = :ck`. +- `LegacyBatchValues`, previously named `BatchValues` - in new API replaced with new trait called (again) `BatchValues`. Represents a source of data for a batch request. It is essentially equivalent to a list of `ValueList`, one for each statement in the batch. For example, `((1, 2), (3, 4, 5))` can be used for a batch with two statements, the first one having two bind markers and the second one having three. + +All methods which take one of the old traits were changed to take the new trait - notably, this includes `Session::query`, `(Caching)Session::execute`, `(Caching)Session::batch`. + +The driver comes a set of `impl`s of those traits which allow to represent any CQL type (for example, see [Data Types](../data-types/data-types.md) page for a list of for which `Value` and `SerializeCql` is implemented). If the driver implements an old trait for some type, then it also provides implements the new trait for the same type. + +## Migration scenarios + +### Different default behavior in `SerializeRow`/`SerializeCql` macros + +By default, the `SerializeRow` and `SerializeCql` **will match the fields in the Rust struct by name to bind marker names** (in case of `SerializeRow`) **or UDT field names** (in case of `SerializeCql`). This is different from the old `ValueList` and `IntoUserType` macros which did not look at the field names at all and would expect the user to order the fields correctly. While the new behavior is much more ergonomic, you might have reasons not to use it. + +> **NOTE:** The deserialization macro counterparts `FromRow` and `FromUserType` have the same limitation as the old serialization macros - they require struct fields to be properly ordered. While a similar rework is planned for the deserialization traits in a future release, for the time being it might not be worth keeping the column names in sync with the database. + +In order to bring the old behavior to the new macros (the only difference being type checking which cannot be disabled right now) you can configure it using attributes, as shown in the snippet below: + +```rust +use scylla::SerializeCql; + +// The exact same attributes apply to the `SerializeRow` macro and their +// effect is completely analogous. +#[derive(SerializeCql)] +#[scylla(flavor = "enforce_order", skip_name_checks)] +struct Person { + name: String, + surname: String, + age: i16, +} +``` + +Refer to the API reference page for the `SerializeRow` and `SerializeCql` macros in the `scylla` crate to learn more about the supported attributes and their meaning. + +### Preparing is mandatory with a non-empty list of values + +> **NOTE:** The considerations in this section only concerns users of the `Session` API, `CachingSession` is not affected as it already does preparation before execute and caches the result. + +As explained in the [Background](#background) section, the driver uses data returned from the database after preparing a statement in order to implement type checking. As the new API makes type checking mandatory, **the driver must prepare the statement** so that the data for the bind markers can be type checked. It is done in case of the existing methods which used to send unprepared statements: `Session::query` and `Session::batch`. + +> **NOTE:** The driver will skip preparation if it detects that the list of values for the statement is empty, as there is nothing to be type checked. + +If you send simple statements along with non-empty lists of values, the slowdown will be as follows: + +- For `Session::query`, the driver will prepare the statement before sending it, incurring an additional round-trip. +- For `Session::batch`, the driver will send a prepare request for each *unique* unprepared statement with a non-empty list of values. **This is done serially!** + +In both cases, if the additional roundtrips are unacceptable, you should prepare the statements beforehand and reuse them - which aligns with our general recommendation against use of simple statements in performance sensitive scenarios. + +### Migrating from old to new traits *gradually* + +In some cases, migration will be as easy as changing occurrences of `IntoUserType` to `SerializeCql` and `ValueList` to `SerializeRow` and adding some atributes for procedural macros. However, if you have a large enough codebase or some custom, complicated implementations of the old traits then you might not want to migrate everything at once. To support gradual migration, the old traits were not removed but rather deprecated, and we introduced some additional utilities. + +#### Converting an object implementing an old trait to a new trait + +We provide a number of newtype wrappers: + +- `ValueAdapter` - implements `SerializeCql` if the type wrapped over implements `Value`, +- `ValueListAdapter` - implements `SerializeRow` if the type wrapped over implements `ValueList`, +- `LegacyBatchValuesAdapter` - implements `BatchValues` if the type wrapped over implements `LegacyBatchValues`. + +Note that these wrappers are not zero cost and incur some overhead: in case of `ValueAdapter` and `ValueListAdapter`, the data is first written into a newly allocated buffer and then rewritten to the final buffer. In case of `LegacyBatchValuesAdapter` there shouldn't be any additional allocations unless the implementation has an efficient, non-default `Self::LegacyBatchValuesIterator::write_next_to_request` implementation (which is not the case for the built-in `impl`s). + +Naturally, the implementations provided by the wrappers are not type safe as they directly use methods from the old traits. + +Conversion in the other direction is not possible. + +#### Custom implementations of old traits + +It is possible to directly generate an `impl` of `SerializeRow` and `SerializeCql` on a type which implements, respectively, `ValueList` or `Value`, without using the wrappers from the previous section. The following macros are provided: + +- `impl_serialize_cql_via_value` - implements `SerializeCql` if the type wrapped over implements `Value`, +- `impl_serialize_row_via_value_list` - implements `SerializeRow` if the type wrapped over implements `ValueList`, + +The implementations are practically as those generated by the wrappers described in the previous section. diff --git a/stable/_sources/migration-guides/migration-guides.md.txt b/stable/_sources/migration-guides/migration-guides.md.txt new file mode 100644 index 0000000000..86887a64c9 --- /dev/null +++ b/stable/_sources/migration-guides/migration-guides.md.txt @@ -0,0 +1,11 @@ +# Migration guides + +- [Serialization changes in version 0.11](0.11-serialization.md) + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + 0.11-serialization +``` diff --git a/stable/_sources/queries/batch.md.txt b/stable/_sources/queries/batch.md.txt new file mode 100644 index 0000000000..271c96baa1 --- /dev/null +++ b/stable/_sources/queries/batch.md.txt @@ -0,0 +1,127 @@ +# Batch statement + +A batch statement allows to execute many data-modifying statements at once.\ +These statements can be [simple](simple.md) or [prepared](prepared.md).\ +Only `INSERT`, `UPDATE` and `DELETE` statements are allowed. + +```rust +use scylla::batch::Batch; +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; + +// Create a batch statement +let mut batch: Batch = Default::default(); + +// Add a simple statement to the batch using its text +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(1, 2)"); + +// Add a simple statement created manually to the batch +let simple: Query = Query::new("INSERT INTO ks.tab (a, b) VALUES(3, 4)"); +batch.append_statement(simple); + +// Add a prepared statement to the batch +let prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a, b) VALUES(?, 6)") + .await?; +batch.append_statement(prepared); + +// Specify bound values to use with each statement +let batch_values = ((), + (), + (5_i32,)); + +// Run the batch +session.batch(&batch, batch_values).await?; +``` + +> ***Warning***\ +> Using simple statements with bind markers in batches is strongly discouraged. +> For each simple statement with a non-empty list of values in the batch, +> the driver will send a prepare request, and it will be done **sequentially**. +> Results of preparation are not cached between `Session::batch` calls. +> Consider preparing the statements before putting them into the batch. + +### Preparing a batch +Instead of preparing each statement individually, it's possible to prepare a whole batch at once: + +```rust +use scylla::batch::Batch; + +// Create a batch statement with unprepared statements +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.simple_unprepared1 VALUES(?, ?)"); +batch.append_statement("INSERT INTO ks.simple_unprepared2 VALUES(?, ?)"); + +// Prepare all statements in the batch at once +let prepared_batch: Batch = session.prepare_batch(&batch).await?; + +// Specify bound values to use with each statement +let batch_values = ((1_i32, 2_i32), + (3_i32, 4_i32)); + +// Run the prepared batch +session.batch(&prepared_batch, batch_values).await?; +``` + +### Batch options +You can set various options by operating on the `Batch` object.\ +For example to change consistency: +```rust +use scylla::batch::Batch; +use scylla::statement::Consistency; + +// Create a batch +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.tab(a) VALUES(16)"); + +// Set batch consistency to One +batch.set_consistency(Consistency::One); + +// Run the batch +session.batch(&batch, ((), )).await?; +``` + +See [Batch API documentation](https://docs.rs/scylla/latest/scylla/statement/batch/struct.Batch.html) +for more options + +### Batch values +Batch takes a tuple of values specified just like in [simple](simple.md) or [prepared](prepared.md) queries. + +Length of batch values must be equal to the number of statements in a batch.\ +Each statement must have its values specified, even if they are empty. + +Values passed to `Session::batch` must implement the trait `BatchValues`.\ +By default this includes tuples `()` and slices `&[]` of tuples and slices which implement `ValueList`. + +Example: +```rust +use scylla::batch::Batch; + +let mut batch: Batch = Default::default(); + +// A statement with two bound values +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(?, ?)"); + +// A statement with one bound value +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(3, ?)"); + +// A statement with no bound values +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(5, 6)"); + +// Batch values is a tuple of 3 tuples containing values for each statement +let batch_values = ((1_i32, 2_i32), // Tuple with two values for the first statement + (4_i32,), // Tuple with one value for the second statement + ()); // Empty tuple/unit for the third statement + +// Run the batch +// Note that the driver will prepare the first two statements, due to them +// not being prepared and having a non-empty list of values. +session.batch(&batch, batch_values).await?; +``` +For more information about sending values in a statement see [Query values](values.md) + + +### Performance +Batch statements do not use token/shard aware load balancing, batches are sent to a random node. + +Use [prepared queries](prepared.md) for best performance diff --git a/stable/_sources/queries/lwt.md.txt b/stable/_sources/queries/lwt.md.txt new file mode 100644 index 0000000000..6efc0659c4 --- /dev/null +++ b/stable/_sources/queries/lwt.md.txt @@ -0,0 +1,26 @@ +# Lightweight transaction (LWT) query + +A lightweight transaction query can be expressed just like any other query, via `Session`, with the notable difference of having an additional consistency level parameter - the `serial_consistency_level`. + + +### Format of the query +A lightweight transaction query is not a separate type - it can be expressed just like any other queries: via `SimpleQuery`, `PreparedStatement`, batches, and so on. The difference lays in the query string itself - when it contains a condition (e.g. `IF NOT EXISTS`), it becomes a lightweight transaction. It's important to remember that CQL specification requires a separate, additional consistency level to be defined for LWT queries - `serial_consistency_level`. The serial consistency level can only be set to two values: `SerialConsistency::Serial` or `SerialConsistency::LocalSerial`. The "local" variant makes the transaction consistent only within the same datacenter. For convenience, Scylla Rust Driver sets the default consistency level to `LocalSerial`, as it's more commonly used. For cross-datacenter consistency, please remember to always override the default with `SerialConsistency::Serial`. +```rust +use scylla::query::Query; +use scylla::statement::{Consistency, SerialConsistency}; + +// Create a Query manually to change the Consistency to ONE +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?) IF NOT EXISTS".to_string()); +my_query.set_consistency(Consistency::One); +// Use cross-datacenter serial consistency +my_query.set_serial_consistency(Some(SerialConsistency::Serial)); + +// Insert a value into the table +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +The rest of the API remains identical for LWT and non-LWT queries. + +See [Query API documentation](https://docs.rs/scylla/latest/scylla/statement/query/struct.Query.html) for more options + diff --git a/stable/_sources/queries/paged.md.txt b/stable/_sources/queries/paged.md.txt new file mode 100644 index 0000000000..ce6173ac72 --- /dev/null +++ b/stable/_sources/queries/paged.md.txt @@ -0,0 +1,118 @@ +# Paged query +Sometimes query results might not fit in a single page. Paged queries +allow to receive the whole result page by page. + +`Session::query_iter` and `Session::execute_iter` take a [simple query](simple.md) or a [prepared query](prepared.md) +and return an `async` iterator over result `Rows`. + +> ***Warning***\ +> In case of unprepared variant (`Session::query_iter`) if the values are not empty +> driver will first fully prepare a query (which means issuing additional request to each +> node in a cluster). This will have a performance penalty - how big it is depends on +> the size of your cluster (more nodes - more requests) and the size of returned +> result (more returned pages - more amortized penalty). In any case, it is preferable to +> use `Session::execute_iter`. + +### Examples +Use `query_iter` to perform a [simple query](simple.md) with paging: +```rust +use scylla::IntoTypedRows; +use futures::stream::StreamExt; + +let mut rows_stream = session + .query_iter("SELECT a, b FROM ks.t", &[]) + .await? + .into_typed::<(i32, i32)>(); + +while let Some(next_row_res) = rows_stream.next().await { + let (a, b): (i32, i32) = next_row_res?; + println!("a, b: {}, {}", a, b); +} +``` + +Use `execute_iter` to perform a [prepared query](prepared.md) with paging: +```rust +use scylla::IntoTypedRows; +use scylla::prepared_statement::PreparedStatement; +use futures::stream::StreamExt; + +let prepared: PreparedStatement = session + .prepare("SELECT a, b FROM ks.t") + .await?; + +let mut rows_stream = session + .execute_iter(prepared, &[]) + .await? + .into_typed::<(i32, i32)>(); + +while let Some(next_row_res) = rows_stream.next().await { + let (a, b): (i32, i32) = next_row_res?; + println!("a, b: {}, {}", a, b); +} +``` + +Query values can be passed to `query_iter` and `execute_iter` just like in a [simple query](simple.md) + +### Configuring page size +It's possible to configure the size of a single page. + +On a `Query`: +```rust +use scylla::query::Query; + +let mut query: Query = Query::new("SELECT a, b FROM ks.t"); +query.set_page_size(16); + +let _ = session.query_iter(query, &[]).await?; // ... +``` + +On a `PreparedStatement`: +```rust +use scylla::prepared_statement::PreparedStatement; + +let mut prepared: PreparedStatement = session + .prepare("SELECT a, b FROM ks.t") + .await?; + +prepared.set_page_size(16); + +let _ = session.execute_iter(prepared, &[]).await?; // ... +``` + +### Passing the paging state manually +It's possible to fetch a single page from the table, extract the paging state +from the result and manually pass it to the next query. That way, the next +query will start fetching the results from where the previous one left off. + +On a `Query`: +```rust +use scylla::query::Query; + +let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6); +let res1 = session.query(paged_query.clone(), &[]).await?; +let res2 = session + .query_paged(paged_query.clone(), &[], res1.paging_state) + .await?; +``` + +> ***Warning***\ +> If the values are not empty, driver first needs to send a `PREPARE` request +> in order to fetch information required to serialize values. This will affect +> performance because 2 round trips will be required instead of 1. + +On a `PreparedStatement`: +```rust +use scylla::query::Query; + +let paged_prepared = session + .prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7)) + .await?; +let res1 = session.execute(&paged_prepared, &[]).await?; +let res2 = session + .execute_paged(&paged_prepared, &[], res1.paging_state) + .await?; +``` + +### Performance +Performance is the same as in non-paged variants.\ +For the best performance use [prepared queries](prepared.md). \ No newline at end of file diff --git a/stable/_sources/queries/prepared.md.txt b/stable/_sources/queries/prepared.md.txt new file mode 100644 index 0000000000..e4551a2ae8 --- /dev/null +++ b/stable/_sources/queries/prepared.md.txt @@ -0,0 +1,108 @@ +# Prepared query + +Prepared queries provide much better performance than simple queries, +but they need to be prepared before use. + +```rust +use scylla::prepared_statement::PreparedStatement; + +// Prepare the query for later execution +let prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +// Run the prepared query with some values, just like a simple query +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` + +> ***Warning***\ +> For token/shard aware load balancing to work properly, all partition key values +> must be sent as bound values (see [performance section](#performance)) + +> ***Warning***\ +> Don't use `execute` to receive large amounts of data.\ +> By default the query is unpaged and might cause heavy load on the cluster. +> In such cases set a page size and use a [paged query](paged.md) instead. +> +> When page size is set, `execute` will return only the first page of results. + +### `Session::prepare` +`Session::prepare` takes query text and prepares the query on all nodes and shards. +If at least one succeeds returns success. + +### `Session::execute` +`Session::execute` takes a prepared query and bound values and runs the query. +Passing values and the result is the same as in [simple query](simple.md). + +### Query options + +To specify custom options, set them on the `PreparedStatement` before execution. +For example to change the consistency: + +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::statement::Consistency; + +// Prepare the query for later execution +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +// Set prepared query consistency to One +// This is the consistency with which this query will be executed +prepared.set_consistency(Consistency::One); + +// Run the prepared query with some values, just like a simple query +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` + +See [PreparedStatement API documentation](https://docs.rs/scylla/latest/scylla/statement/prepared_statement/struct.PreparedStatement.html) +for more options. + +> ***Note*** +> Prepared statements can be created from `Query` structs and will inherit from +> the custom options that the `Query` was created with. +> This is especially useful when using `CachingSession::execute` for example. + +### Performance + +Prepared queries have good performance, much better than simple queries. +By default they use shard/token aware load balancing. + +> **Always** pass partition key values as bound values. +> Otherwise the driver can't hash them to compute partition key +> and they will be sent to the wrong node, which worsens performance. + +Let's say we have a table like this: + +```sql +TABLE ks.prepare_table ( + a int, + b int, + c int, + PRIMARY KEY (a, b) +) +``` + +```rust +use scylla::prepared_statement::PreparedStatement; + +// WRONG - partition key value is passed in query string +// Load balancing will compute the wrong partition key +let wrong_prepared: PreparedStatement = session + .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(12345, ?, 16)") + .await?; + +session.execute(&wrong_prepared, (54321,)).await?; + +// GOOD - partition key values are sent as bound values +// Other values can be sent any way you like, it doesn't matter +let good_prepared: PreparedStatement = session + .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(?, ?, 16)") + .await?; + +session.execute(&good_prepared, (12345, 54321)).await?; + +``` diff --git a/stable/_sources/queries/queries.md.txt b/stable/_sources/queries/queries.md.txt new file mode 100644 index 0000000000..b75810d0ad --- /dev/null +++ b/stable/_sources/queries/queries.md.txt @@ -0,0 +1,39 @@ +# Making queries + +This driver supports all query types available in Scylla: +* [Simple queries](simple.md) + * Easy to use + * Poor performance + * Primitive load balancing +* [Prepared queries](prepared.md) + * Need to be prepared before use + * Fast + * Properly load balanced +* [Batch statements](batch.md) + * Run multiple queries at once + * Can be prepared for better performance and load balancing +* [Paged queries](paged.md) + * Allows to read result in multiple pages when it doesn't fit in a single response + * Can be prepared for better performance and load balancing + +Additionally there is special functionality to enable `USE KEYSPACE` queries: +[USE keyspace](usekeyspace.md) + +Queries are fully asynchronous - you can run as many of them in parallel as you wish. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + simple + values + result + prepared + batch + paged + usekeyspace + schema-agreement + lwt + timeouts +``` diff --git a/stable/_sources/queries/result.md.txt b/stable/_sources/queries/result.md.txt new file mode 100644 index 0000000000..0374599301 --- /dev/null +++ b/stable/_sources/queries/result.md.txt @@ -0,0 +1,115 @@ +# Query result + +`Session::query` and `Session::execute` return a `QueryResult` with rows represented as `Option>`. + +### Basic representation +`Row` is a basic representation of a received row. It can be used by itself, but it's a bit awkward to use: +```rust +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows { + let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap(); + } +} +``` + +### Parsing using `into_typed` +The driver provides a way to parse a row as a tuple of Rust types: +```rust +use scylla::IntoTypedRows; + +// Parse row as a single column containing an int value +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows { + let (int_value,): (i32,) = row.into_typed::<(i32,)>()?; + } +} + +// rows.into_typed() converts a Vec of Rows to an iterator of parsing results +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32,)>() { + let (int_value,): (i32,) = row?; + } +} + +// Parse row as two columns containing an int and text columns +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32, String)>() { + let (int_value, text_value): (i32, String) = row?; + } +} +``` + +## Parsing using convenience methods +[`QueryResult`](https://docs.rs/scylla/latest/scylla/transport/query_result/struct.QueryResult.html) provides convenience methods for parsing rows. +Here are a few of them: +* `rows_typed::()` - returns the rows parsed as the given type +* `maybe_first_row_typed::` - returns `Option` containing first row from the result +* `first_row_typed::` - same as `maybe_first_row`, but fails without the first row +* `single_row_typed::` - same as `first_row`, but fails when there is more than one row +* `result_not_rows()` - ensures that query response was not `rows`, helps avoid bugs + + +```rust +// Parse row as a single column containing an int value +let rows = session + .query("SELECT a from ks.tab", &[]) + .await? + .rows_typed::<(i32,)>()?; // Same as .rows()?.into_typed() +for row in rows { + let (int_value,): (i32,) = row?; +} + +// maybe_first_row_typed gets the first row and parses it as the given type +let first_int_val: Option<(i32,)> = session + .query("SELECT a from ks.tab", &[]) + .await? + .maybe_first_row_typed::<(i32,)>()?; + +// no_rows fails when the response is rows +session.query("INSERT INTO ks.tab (a) VALUES (0)", &[]).await?.result_not_rows()?; +``` +For more see [`QueryResult`](https://docs.rs/scylla/latest/scylla/transport/query_result/struct.QueryResult.html) + +### `NULL` values +`NULL` values will return an error when parsed as a Rust type. +To properly handle `NULL` values parse column as an `Option<>`: +```rust +use scylla::IntoTypedRows; + +// Parse row as two columns containing an int and text which might be null +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32, Option)>() { + let (int_value, str_or_null): (i32, Option) = row?; + } +} +``` + +### Parsing row as a custom struct +It is possible to receive row as a struct with fields matching the columns.\ +The struct must: +* have the same number of fields as the number of queried columns +* have field types matching the columns being received +* derive `FromRow` + +Field names don't need to match column names. +```rust +use scylla::IntoTypedRows; +use scylla::macros::FromRow; +use scylla::frame::response::cql_to_rust::FromRow; + +#[derive(FromRow)] +struct MyRow { + age: i32, + name: Option +} + +// Parse row as two columns containing an int and text which might be null +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::() { + let my_row: MyRow = row?; + } +} +``` + +### Other data types +For parsing other data types see [Data Types](../data-types/data-types.md) \ No newline at end of file diff --git a/stable/_sources/queries/schema-agreement.md.txt b/stable/_sources/queries/schema-agreement.md.txt new file mode 100644 index 0000000000..a7163af7dd --- /dev/null +++ b/stable/_sources/queries/schema-agreement.md.txt @@ -0,0 +1,53 @@ +# Schema agreement + +Sometimes after performing queries some nodes have not been updated, so we need a mechanism that checks if every node have agreed on schema version. + +### Automated awaiting schema agreement + +The driver automatically awaits schema agreement after a schema-altering query is executed. +Waiting for schema agreement more than necessary is never a bug, but might slow down applications which do a lot of schema changes (e.g. a migration). +For instance, in case where somebody wishes to create a keyspace and then a lot of tables in it, it makes sense only to wait after creating a keyspace +and after creating all the tables rather than after every query. Therefore, the said behaviour can be disabled: + +```rust +let session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .auto_await_schema_agreement(false) + .build() + .await?; +``` + +### Manually awaiting schema agreement + +`Session::await_schema_agreement` returns a `Future` that can be `await`ed as long as schema is not in an agreement. +However, it won't wait forever; `SessionConfig` defines a timeout that limits the time of waiting. If the timeout elapses, +the return value is `Err(QueryError::RequestTimeout)`, otherwise it is `Ok(schema_version)`. + +```rust +session.await_schema_agreement().await?; +``` + +### Interval of checking for schema agreement + +If the schema is not agreed upon, the driver sleeps for a duration before checking it again. The default value is 200 milliseconds, +but it can be changed with `SessionBuilder::schema_agreement_interval`. + +```rust +SessionBuilder::new() + .known_node("127.0.0.1:9042") + .schema_agreement_interval(Duration::from_secs(1)) + .build() + .await?; +``` + +### Checking if schema is in agreement now + +If you want to check if schema is in agreement now, without retrying after failure, you can use `Session::check_schema_agreement` function. + +```rust +if session.check_schema_agreement().await?.is_some() { + println!("SCHEMA AGREED"); +} else { + println!("SCHEMA IS NOT IN AGREEMENT"); +} +``` diff --git a/stable/_sources/queries/simple.md.txt b/stable/_sources/queries/simple.md.txt new file mode 100644 index 0000000000..cb6de9eb22 --- /dev/null +++ b/stable/_sources/queries/simple.md.txt @@ -0,0 +1,82 @@ +# Simple query + +Simple query takes query text and values and simply executes them on a `Session`: +```rust +// Insert a value into the table +let to_insert: i32 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; +``` + +> ***Warning***\ +> Don't use simple query to receive large amounts of data.\ +> By default the query is unpaged and might cause heavy load on the cluster.\ +> In such cases set a page size and use [paged query](paged.md) instead.\ +> +> When page size is set, `query` will return only the first page of results. + +> ***Warning***\ +> If the values are not empty, driver first needs to send a `PREPARE` request +> in order to fetch information required to serialize values. This will affect +> performance because 2 round trips will be required instead of 1. + +### First argument - the query +As the first argument `Session::query` takes anything implementing `Into`.\ +You can create a query manually to set custom options. For example to change query consistency: +```rust +use scylla::query::Query; +use scylla::statement::Consistency; + +// Create a Query manually to change the Consistency to ONE +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_consistency(Consistency::One); + +// Insert a value into the table +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` +See [Query API documentation](https://docs.rs/scylla/latest/scylla/statement/query/struct.Query.html) for more options + +### Second argument - the values +Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.\ +Each `?` in query text will be filled with the matching value. + +The easiest way is to pass values using a tuple: +```rust +// Sending an integer and a string using a tuple +session + .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, 'text2')", (2_i32, "Some text")) + .await?; +``` +Here the first `?` will be filled with `2` and the second with `"Some text"`. +> **Never** pass values by adding strings, this could lead to [SQL Injection](https://en.wikipedia.org/wiki/SQL_injection) + +See [Query values](values.md) for more information about sending values in queries + +### Query result +`Session::query` returns `QueryResult` with rows represented as `Option>`.\ +Each row can be parsed as a tuple of rust types using `rows_typed`: +```rust +use scylla::IntoTypedRows; + +// Query rows from the table and print them +let result = session.query("SELECT a FROM ks.tab", &[]).await?; +let mut iter = result.rows_typed::<(i32,)>()?; +while let Some(read_row) = iter.next().transpose()? { + println!("Read a value from row: {}", read_row.0); +} +``` +> In cases where page size is set, simple query returns only a single page of results.\ +> To receive all pages use a [paged query](paged.md) instead.\ + +See [Query result](result.md) for more information about handling query results + +### Performance +Simple queries should not be used in places where performance matters.\ +If performance matters use a [Prepared query](prepared.md) instead. + +With simple query the database has to parse query text each time it's executed, which worsens performance.\ + +Additionally token and shard aware load balancing does not work with simple queries. They are sent to random nodes. diff --git a/stable/_sources/queries/timeouts.md.txt b/stable/_sources/queries/timeouts.md.txt new file mode 100644 index 0000000000..16e4af1ca3 --- /dev/null +++ b/stable/_sources/queries/timeouts.md.txt @@ -0,0 +1,53 @@ +# Query timeouts + +Query execution time can be limited by setting a request timeout. If a query does not complete +in the given time, then `QueryError::RequestTimeout` is returned by the driver immediately, +so that application logic can continue operating, but the query may still be in progress on the server. + +As a side note, if one wishes custom server-side timeouts (i.e. actual interruption of query processing), +one can use a[`USING TIMEOUT ` directive supported in ScyllaDB](https://github.com/scylladb/scylladb/blob/master/docs/cql/cql-extensions.md#using-timeout) +(but not in Cassandra). + +Timeout can be set globally (per session) or locally (for given statement). +The default per-session timeout is currently 30s. +It is possible to turn off timeouts completely by providing `None` as timeout when building `Session`. +However, setting per-statement timeout to `None` results in falling back to per-session timeout. + +```rust +use scylla::{Session, SessionBuilder, query::Query}; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + +let no_timeout_profile_handle = ExecutionProfile::builder() + .request_timeout(None) // no timeout + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node(uri) + .default_execution_profile_handle(no_timeout_profile_handle) // no per-session timeout + .build() + .await?; + +// This query, having no timeout, could block indefinitely if a queried node hangs. +session + .query("TRUNCATE keyspace.table", ()) + .await?; + +let three_sec_timeout_profile_handle = ExecutionProfile::builder() + .request_timeout(Some(Duration::from_secs(3))) // no timeout + .build() + .into_handle(); + +// The below query will last for no more than 3 seconds, yielding a RequestTimeout error +// if no response arrives until then. +let mut query: Query = "TRUNCATE keyspace.table".into(); +query.set_execution_profile_handle(Some(three_sec_timeout_profile_handle)); +session + .query(query, ()) + .await?; + +``` diff --git a/stable/_sources/queries/usekeyspace.md.txt b/stable/_sources/queries/usekeyspace.md.txt new file mode 100644 index 0000000000..7b9afabeb6 --- /dev/null +++ b/stable/_sources/queries/usekeyspace.md.txt @@ -0,0 +1,77 @@ +# USE keyspace + +Using a keyspace allows to omit keyspace name in queries. + +For example in `cqlsh` one could write: +```sql +cqlsh> SELECT * FROM my_keyspace.table; + + a | b | +-------+-------+ + 12345 | 54321 | + +(1 rows) +cqlsh> USE my_keyspace; +cqlsh:my_keyspace> SELECT * FROM table; + + a | b | +-------+-------+ + 12345 | 54321 | + +(1 rows) + +``` +Tables from other keyspaces can still easily be accessed by using their keyspace names. +```sql +cqlsh:my_keyspace> SELECT * FROM other_keyspace.other_table; +``` + +In the driver this can be achieved using `Session::use_keyspace`: +```rust +session + .query("INSERT INTO my_keyspace.tab (a) VALUES ('test1')", &[]) + .await?; + +session.use_keyspace("my_keyspace", false).await?; + +// Now we can omit keyspace name in the query +session + .query("INSERT INTO tab (a) VALUES ('test2')", &[]) + .await?; +``` + +The first argument is the keyspace name.\ +The second argument states whether this name is case sensitive. + +It is also possible to send raw use keyspace query using `Session::query` instead of `Session::use_keyspace` such as: +```rust +session.query("USE my_keyspace", &[]).await?; +``` +This method has a slightly worse latency than `Session::use_keyspace` - there are two roundtrips needed instead of one. +Therefore, `Session::use_keyspace` is the preferred method for setting keyspaces. + +### Multiple use queries at once +Don't run multiple `use_keyspace` queries at once. +This could end up with half of connections using one keyspace and the other half using the other. + +### Case sensitivity + +In CQL a keyspace name can be case insensitive (without `"`) or case sensitive (with `"`).\ +If the second argument to `use_keyspace` is set to `true` this keyspace name will be wrapped in `"`.\ +It is best to avoid the problem altogether and just not create two keyspaces with the same name but different cases. + +Let's see what happens when there are two keyspaces with the same name but different cases: `my_keyspace` and `MY_KEYSPACE`: + +```rust +// lowercase name without case sensitivity will use my_keyspace +session.use_keyspace("my_keyspace", false).await?; + +// lowercase name with case sensitivity will use my_keyspace +session.use_keyspace("my_keyspace", true).await?; + +// uppercase name without case sensitivity will use my_keyspace +session.use_keyspace("MY_KEYSPACE", false).await?; + +// uppercase name with case sensitivity will use MY_KEYSPACE +session.use_keyspace("MY_KEYSPACE", true).await?; +``` diff --git a/stable/_sources/queries/values.md.txt b/stable/_sources/queries/values.md.txt new file mode 100644 index 0000000000..caddca4036 --- /dev/null +++ b/stable/_sources/queries/values.md.txt @@ -0,0 +1,125 @@ +# Query values +Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.\ +Each `?` in query text will be filled with the matching value. + +> **Never** pass values by adding strings, this could lead to [SQL Injection](https://en.wikipedia.org/wiki/SQL_injection) + +Each list of values to send in a query must implement the trait `SerializeRow`.\ +By default this can be a slice `&[]`, a tuple `()` (max 16 elements) of values to send, +or a custom struct which derives from `SerializeRow`. + +A few examples: +```rust +// Empty slice means that there are no values to send +session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?; + +// Empty tuple/unit also means that there are no values to send +session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?; + +// Sending three integers using a slice: +session + .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref()) + .await?; + +// Sending an integer and a string using a tuple +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text")) + .await?; + +// Sending an integer and a string using a named struct. +// Names of fields must match names of columns in request, +// but having them in the same order is not required. +// If the fields are in the same order, you can use attribute: +// `#[scylla(flavor = "enforce_order")]` +// in order to skip sorting the fields and just check if they +// are in the same order. See documentation of this macro +// for more information. +#[derive(SerializeRow)] +struct IntString { + a: i32, + b: String, +} + +let int_string = IntString { + a: 42_i32, + b: "hello".to_owned(), +}; + +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string) + .await?; + +// You can use named bind markers in query if you want +// your names in struct to be different than column names. +#[derive(SerializeRow)] +struct IntStringCustom { + first_value: i32, + second_value: String, +} + +let int_string_custom = IntStringCustom { + first_value: 42_i32, + second_value: "hello".to_owned(), +}; + +session + .query("INSERT INTO ks.tab (a, b) VALUES(:first_value, :second_value)", int_string_custom) + .await?; + +// Sending a single value as a tuple requires a trailing coma (Rust syntax): +session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?; + +// Each value can also be sent using a reference: +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text")) + .await?; + +// A map of named values can also be provided: +let mut vals: HashMap<&str, CqlValue> = HashMap::new(); +vals.insert("avalue", CqlValue::Text("hello".to_string())); +vals.insert("bvalue", CqlValue::Int(17)); +session + .query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals) + .await?; + +``` + +### `NULL` values +Null values can be sent using `Option<>` - sending a `None` will make the value `NULL`: +```rust +let null_i32: Option = None; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,)) + .await?; +``` + +### `Unset` values +When performing an insert with values which might be `NULL`, it's better to use `Unset`.\ +Database treats inserting `NULL` as a delete operation and will generate a tombstone. +Using `Unset` results in better performance: + +```rust +use scylla::frame::value::{MaybeUnset, Unset}; + +// Inserting a null results in suboptimal performance +let null_i32: Option = None; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,)) + .await?; + +// Using MaybeUnset enum is better +let unset_i32: MaybeUnset = MaybeUnset::Unset; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,)) + .await?; + +// If we are sure that a value should be unset we can simply use Unset +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,)) + .await?; +``` +See the [issue](https://issues.apache.org/jira/browse/CASSANDRA-7304) for more information about `Unset` + +### Other data types +See [Data Types](../data-types/data-types.md) for instructions on sending other data types diff --git a/stable/_sources/quickstart/create-project.md.txt b/stable/_sources/quickstart/create-project.md.txt new file mode 100644 index 0000000000..41f9b6228f --- /dev/null +++ b/stable/_sources/quickstart/create-project.md.txt @@ -0,0 +1,34 @@ +# Creating a project + +To create a new project run: +```shell +cargo new myproject +``` + +In `Cargo.toml` add useful dependencies: +```toml +[dependencies] +scylla = "0.13" +tokio = { version = "1.12", features = ["full"] } +futures = "0.3.6" +uuid = "1.0" +bigdecimal = "0.4" +num-bigint = "0.3" +tracing = "0.1.36" +tracing-subscriber = { version = "0.3.14", features = ["env-filter"] } +``` + +In `main.rs` put: +```rust +use scylla::Session; + +#[tokio::main] +async fn main() { + println!("Hello scylla!"); +} +``` + +Now running `cargo run` should print: +```shell +Hello scylla! +``` diff --git a/stable/_sources/quickstart/example.md.txt b/stable/_sources/quickstart/example.md.txt new file mode 100644 index 0000000000..a543c7d40b --- /dev/null +++ b/stable/_sources/quickstart/example.md.txt @@ -0,0 +1,52 @@ +# Connecting and running a simple query + +Now everything is ready to use the driver. +Here is a small example: +```rust +use scylla::{IntoTypedRows, Session, SessionBuilder}; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new Session which connects to node at 127.0.0.1:9042 + // (or SCYLLA_URI if specified) + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .build() + .await?; + + // Create an example keyspace and table + session + .query( + "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \ + {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}", + &[], + ) + .await?; + + session + .query( + "CREATE TABLE IF NOT EXISTS ks.extab (a int primary key)", + &[], + ) + .await?; + + // Insert a value into the table + let to_insert: i32 = 12345; + session + .query("INSERT INTO ks.extab (a) VALUES(?)", (to_insert,)) + .await?; + + // Query rows from the table and print them + let result = session.query("SELECT a FROM ks.extab", &[]).await?; + let mut iter = result.rows_typed::<(i32,)>()?; + while let Some(read_row) = iter.next().transpose()? { + println!("Read a value from row: {}", read_row.0); + } + + Ok(()) +} +``` diff --git a/stable/_sources/quickstart/quickstart.md.txt b/stable/_sources/quickstart/quickstart.md.txt new file mode 100644 index 0000000000..b544aef743 --- /dev/null +++ b/stable/_sources/quickstart/quickstart.md.txt @@ -0,0 +1,23 @@ + +# Quick Start + + +In this chapter we will set up a Rust project and run a few simple queries. + +Topics Include: + +* [Create a Rust Project](create-project.md) +* [Example](example.md) +* [Install Scylla with Docker](scylla-docker.md) + + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + create-project + example + scylla* + +``` \ No newline at end of file diff --git a/stable/_sources/quickstart/scylla-docker.md.txt b/stable/_sources/quickstart/scylla-docker.md.txt new file mode 100644 index 0000000000..849bcbc10e --- /dev/null +++ b/stable/_sources/quickstart/scylla-docker.md.txt @@ -0,0 +1,23 @@ +# Running Scylla using Docker + +To make queries we will need a running Scylla instance. The easiest way is to use a [Docker](https://www.docker.com/) image.\ +Please [install Docker](https://docs.docker.com/engine/install) if it's not installed. + +### Running scylla +To start Scylla run: +```bash +# on Linux sudo might be required +docker run --rm -it -p 9042:9042 scylladb/scylla --smp 2 +``` + +Docker will download the image, then after minute or two there should be a message like: +```shell +Starting listening for CQL clients on 172.17.0.2:9042 +``` +This means that Scylla is ready to receive queries + +To stop this instance press `Ctrl + C` + +### More information +More information about this image can be found on [dockerhub](https://hub.docker.com/r/scylladb/scylla) + diff --git a/stable/_sources/retry-policy/default.md.txt b/stable/_sources/retry-policy/default.md.txt new file mode 100644 index 0000000000..590b503730 --- /dev/null +++ b/stable/_sources/retry-policy/default.md.txt @@ -0,0 +1,69 @@ +# Default retry policy +This is the retry policy used by default. It retries when there is a high chance that it might help.\ +This policy is based on the one in [DataStax Java Driver](https://docs.datastax.com/en/developer/java-driver/4.11/manual/core/retries/). +The behaviour is the same. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new()))); + +// You can also set retry policy in an execution profile +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; +prepared.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new()))); + +// You can also set retry policy in an execution profile +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); +prepared.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/stable/_sources/retry-policy/downgrading-consistency.md.txt b/stable/_sources/retry-policy/downgrading-consistency.md.txt new file mode 100644 index 0000000000..a13aea35f0 --- /dev/null +++ b/stable/_sources/retry-policy/downgrading-consistency.md.txt @@ -0,0 +1,108 @@ +# Downgrading consistency retry policy + +A retry policy that sometimes retries with a lower consistency level than the one initially +requested. +**BEWARE**: this policy may retry queries using a lower consistency level than the one +initially requested. By doing so, it may break consistency guarantees. In other words, if you use +this retry policy, there are cases (documented below) where a read at `Consistency::Quorum` **may +not** see a preceding write at `Consistency::Quorum`. Do not use this policy unless you have +understood the cases where this can happen and are ok with that. It is also highly recommended to +always log the occurrences of such consistency breaks. +This policy implements the same retries than the [DefaultRetryPolicy](default.md) policy. But on top +of that, it also retries in the following cases: + - On a read timeout: if the number of replicas that responded is greater than one, but lower + than is required by the requested consistency level, the operation is retried at a lower + consistency level. + - On a write timeout: if the operation is a `WriteType::UnloggedBatch` and at least one + replica acknowledged the write, the operation is retried at a lower consistency level. + Furthermore, for other operations, if at least one replica acknowledged the write, the + timeout is ignored. + - On an unavailable exception: if at least one replica is alive, the operation is retried at + a lower consistency level. + +The lower consistency level to use for retries is determined by the following rules: + - if more than 3 replicas responded, use `Consistency::Three`. + - if 1, 2 or 3 replicas responded, use the corresponding level `Consistency::One`, `Consistency::Two` or + `Consistency::Three`. + +Note that if the initial consistency level was `Consistency::EachQuorum`, Scylla returns the number +of live replicas _in the datacenter that failed to reach consistency_, not the overall +number in the cluster. Therefore if this number is 0, we still retry at `Consistency::One`, on the +assumption that a host may still be up in another datacenter. +The reasoning being this retry policy is the following one. If, based on the information the +Scylla coordinator node returns, retrying the operation with the initially requested +consistency has a chance to succeed, do it. Otherwise, if based on this information we know +**the initially requested consistency level cannot be achieved currently**, then: + - For writes, ignore the exception (thus silently failing the consistency requirement) if we + know the write has been persisted on at least one replica. + - For reads, try reading at a lower consistency level (thus silently failing the consistency + requirement). +In other words, this policy implements the idea that if the requested consistency level cannot be +achieved, the next best thing for writes is to make sure the data is persisted, and that reading +something is better than reading nothing, even if there is a risk of reading stale data. + +This policy is based on the one in [DataStax Java Driver](https://docs.datastax.com/en/drivers/java/3.11/com/datastax/driver/core/policies/DowngradingConsistencyRetryPolicy.html). +The behaviour is the same. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +prepared.set_execution_profile_handle(Some(handle)); + + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/stable/_sources/retry-policy/fallthrough.md.txt b/stable/_sources/retry-policy/fallthrough.md.txt new file mode 100644 index 0000000000..ca4cd44947 --- /dev/null +++ b/stable/_sources/retry-policy/fallthrough.md.txt @@ -0,0 +1,65 @@ +# Fallthrough retry policy + +The `FalthroughRetryPolicy` never retries, returns errors straight to the user. Useful for debugging. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +prepared.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/stable/_sources/retry-policy/retry-policy.md.txt b/stable/_sources/retry-policy/retry-policy.md.txt new file mode 100644 index 0000000000..68c4726dc0 --- /dev/null +++ b/stable/_sources/retry-policy/retry-policy.md.txt @@ -0,0 +1,48 @@ +# Retry policy configuration + +After a query fails the driver might decide to retry it based on its `Retry Policy` and the query itself. +Retry policy can be configured for `Session` or just for a single query. + +### Retry policies +By default there are three retry policies: +* [Fallthrough Retry Policy](fallthrough.md) - never retries, returns all errors straight to the user +* [Default Retry Policy](default.md) - used by default, might retry if there is a high chance of success +* [Downgrading Consistency Retry Policy](downgrading-consistency.md) - behaves as [Default Retry Policy](default.md), but also, + in some more cases, it retries **with lower `Consistency`**. + +It's possible to implement a custom `Retry Policy` by implementing the traits `RetryPolicy` and `RetrySession`. + +### Query idempotence +A query is idempotent if it can be applied multiple times without changing the result of the initial application + +Specifying that a query is idempotent increases the chances that it will be retried in case of failure. +Idempotent queries can be retried in situations where retrying non idempotent queries would be dangerous. + +Idempotence has to be specified manually, the driver is not able to figure it out by itself. +```rust +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; + +// Specify that a Query is idempotent +let mut my_query: Query = Query::new("SELECT a FROM ks.tab"); +my_query.set_is_idempotent(true); + + +// Specify that a PreparedStatement is idempotent +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +prepared.set_is_idempotent(true); +``` + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + fallthrough + default + downgrading-consistency + +``` diff --git a/stable/_sources/schema/schema.md.txt b/stable/_sources/schema/schema.md.txt new file mode 100644 index 0000000000..19a5bc9751 --- /dev/null +++ b/stable/_sources/schema/schema.md.txt @@ -0,0 +1,60 @@ +# Schema + +The driver is capable of fetching database schema and presenting it to its users. + +## Fetching schema + +Fetching database schema occurs periodically, but it can also be done on-demand. In order to fetch the newest database schema, one can call `refresh_metadata()` on a Session instance: +```rust + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + // Schema metadata will be fetched below + session.refresh_metadata().await?; + Ok(()) +} +``` + +## Inspecting schema + +Once fetched, a snapshot of cluster's schema can be examined. The following information can be obtained: + - keyspace + - tables belonging to the keyspace + - materialized views belonging to the keyspace + - replication strategy + - user-defined types + - table/view + - primary key definition + - columns + - partitioner type + +Example showing how to print obtained schema information: + +```rust + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + // Schema metadata will be fetched below + session.refresh_metadata().await?; + + let cluster_data = &session.get_cluster_data(); + let keyspaces = &cluster_data.get_keyspace_info(); + + for (keyspace_name, keyspace_info) in keyspaces.iter() { + println!("Keyspace {}:", keyspace_name); + println!("\tTables: {:#?}", keyspace_info.tables); + println!("\tViews: {:#?}", keyspace_info.views); + println!("\tUDTs: {:#?}", keyspace_info.user_defined_types); + } + + Ok(()) +} +``` diff --git a/stable/_sources/speculative-execution/percentile.md.txt b/stable/_sources/speculative-execution/percentile.md.txt new file mode 100644 index 0000000000..c82c24a925 --- /dev/null +++ b/stable/_sources/speculative-execution/percentile.md.txt @@ -0,0 +1,34 @@ +# Percentile speculative execution + +This policy has access to `Metrics` shared with session, and triggers +speculative execution when the request to the current host is above a +given percentile. + + +### Example +To use this policy in `Session`: +```rust +use std::{sync::Arc, time::Duration}; +use scylla::{ + Session, + SessionBuilder, + speculative_execution::PercentileSpeculativeExecutionPolicy, + transport::execution_profile::ExecutionProfile, +}; + +let policy = PercentileSpeculativeExecutionPolicy { + max_retry_count: 3, + percentile: 99.0, +}; + +let handle = ExecutionProfile::builder() + .speculative_execution_policy(Some(Arc::new(policy))) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` diff --git a/stable/_sources/speculative-execution/simple.md.txt b/stable/_sources/speculative-execution/simple.md.txt new file mode 100644 index 0000000000..dd17db55d6 --- /dev/null +++ b/stable/_sources/speculative-execution/simple.md.txt @@ -0,0 +1,34 @@ +# Simple speculative execution + +The easiest speculative execution policy available. It starts another +execution of a query after constant delay of `retry_interval` and does at most +`max_retry_count` speculative query executions (not counting the first, +non-speculative one). + +### Example +To use this policy in `Session`: +```rust +use std::{sync::Arc, time::Duration}; +use scylla::{ + Session, + SessionBuilder, + speculative_execution::SimpleSpeculativeExecutionPolicy, + transport::execution_profile::ExecutionProfile, +}; + +let policy = SimpleSpeculativeExecutionPolicy { + max_retry_count: 3, + retry_interval: Duration::from_millis(100), +}; + +let handle = ExecutionProfile::builder() + .speculative_execution_policy(Some(Arc::new(policy))) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` diff --git a/stable/_sources/speculative-execution/speculative.md.txt b/stable/_sources/speculative-execution/speculative.md.txt new file mode 100644 index 0000000000..d6e2ae0422 --- /dev/null +++ b/stable/_sources/speculative-execution/speculative.md.txt @@ -0,0 +1,26 @@ +# Speculative execution + +Speculative query execution is an optimization technique where a driver +pre-emptively starts a second execution of a query against another node, +before the first node has replied. + +There are multiple speculative execution strategies that the driver can use. +Speculative execution can be configured for the whole whole `Session` during +its creation. + +Available speculative execution strategies: +* [Simple](simple.md) +* [Latency Percentile](percentile.md) + +Speculative execution is not enabled by default, and currently only +non-iter session methods use it. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + simple + percentile + +``` \ No newline at end of file diff --git a/stable/_sources/tracing/basic.md.txt b/stable/_sources/tracing/basic.md.txt new file mode 100644 index 0000000000..73a6cb227c --- /dev/null +++ b/stable/_sources/tracing/basic.md.txt @@ -0,0 +1,74 @@ +# Tracing a simple/prepared/batch query + +[Simple query](../queries/simple.md), [prepared query](../queries/prepared.md) and [batch query](../queries/batch.md) +return a `QueryResult` which contains a `tracing_id` if tracing was enabled. + +### Tracing a simple query +```rust +use scylla::query::Query; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Create a Query manually and enable tracing +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)"); +query.set_tracing(true); + +let res: QueryResult = session.query(query, &[]).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing a prepared query +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Prepare the query +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +// Enable tracing for the prepared query +prepared.set_tracing(true); + +let res: QueryResult = session.execute(&prepared, &[]).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing a batch query +```rust +use scylla::batch::Batch; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Create a batch statement +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.tab (a) VALUES(4)"); + +// Enable tracing +batch.set_tracing(true); + +let res: QueryResult = session.batch(&batch, ((),)).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/stable/_sources/tracing/paged.md.txt b/stable/_sources/tracing/paged.md.txt new file mode 100644 index 0000000000..e7424e6ddd --- /dev/null +++ b/stable/_sources/tracing/paged.md.txt @@ -0,0 +1,65 @@ +# Tracing a paged query + +A paged query performs multiple simple/prepared queries to query subsequent pages.\ +If tracing is enabled the row iterator will contain a list of tracing ids for all performed queries. + + +### Tracing `Session::query_iter` +```rust +use scylla::query::Query; +use scylla::transport::iterator::RowIterator; +use scylla::tracing::TracingInfo; +use futures::StreamExt; +use uuid::Uuid; + +// Create a Query manually and enable tracing +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)"); +query.set_tracing(true); + +// Create a paged query iterator and fetch pages +let mut row_iterator: RowIterator = session.query_iter(query, &[]).await?; +while let Some(_row) = row_iterator.next().await { + // Receive rows +} + +// Now there are tracing ids for each performed query +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids(); + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing `Session::execute_iter` +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::iterator::RowIterator; +use scylla::tracing::TracingInfo; +use futures::StreamExt; +use uuid::Uuid; + +// Prepare the query +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +// Enable tracing for the prepared query +prepared.set_tracing(true); + +// Create a paged query iterator and fetch pages +let mut row_iterator: RowIterator = session.execute_iter(prepared, &[]).await?; +while let Some(_row) = row_iterator.next().await { + // Receive rows +} + +// Now there are tracing ids for each performed query +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids(); + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/stable/_sources/tracing/prepare.md.txt b/stable/_sources/tracing/prepare.md.txt new file mode 100644 index 0000000000..98ceafe5d3 --- /dev/null +++ b/stable/_sources/tracing/prepare.md.txt @@ -0,0 +1,27 @@ +# Tracing `Session::prepare` + +`Session::prepare` prepares a query on all connections. If tracing is enabled for the `Query` to prepare, the resulting `PreparedStatement` will contain `prepare_tracing_ids`. `prepare_tracing_ids` is a list of tracing ids of prepare requests on all connections. + +```rust +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Prepare the query with tracing enabled +let mut to_prepare: Query = Query::new("SELECT a FROM ks.tab"); +to_prepare.set_tracing(true); + +let mut prepared: PreparedStatement = session + .prepare(to_prepare) + .await?; + +// Now there are tracing ids for each prepare request +let tracing_ids: &[Uuid] = &prepared.prepare_tracing_ids; + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/stable/_sources/tracing/query-history.md.txt b/stable/_sources/tracing/query-history.md.txt new file mode 100644 index 0000000000..feb7c86be2 --- /dev/null +++ b/stable/_sources/tracing/query-history.md.txt @@ -0,0 +1,106 @@ +# Query Execution History + +The driver allows to collect history of query execution.\ +This history includes all requests sent, decisions to retry and speculative execution fibers started. + +## Example code + +```rust +use scylla::query::Query; +use scylla::history::{HistoryCollector, StructuredHistory}; +use std::sync::Arc; + +// Create a query for which we would like to trace the history of its execution +let mut query: Query = Query::new("SELECT * FROM ks.t"); + +// Create a history collector and pass it to the query +let history_listener = Arc::new(HistoryCollector::new()); +query.set_history_listener(history_listener.clone()); + +// Run the query, doesn't matter if it failed, the history will still be saved +let _ignore_error = session.query(query.clone(), ()).await; + +// Access the collected history and print it +let structured_history: StructuredHistory = history_listener.clone_structured_history(); +println!("Query history: {}", structured_history); +``` +To see more check out the [example code](https://github.com/scylladb/scylla-rust-driver/blob/main/examples/query_history.rs) + +## Output + +Sample output for a query that didn't encounter any difficulties: +```none +=== Query #0 === +| start_time: 2022-08-25 11:21:50.445075147 UTC +| Non-speculative attempts: +| - Attempt #0 sent to 127.0.0.1:9042 +| request send time: 2022-08-25 11:21:50.445151628 UTC +| Success at 2022-08-25 11:21:50.447444362 UTC +| +| Query successful at 2022-08-25 11:21:50.447447970 UTC +================= +``` + +Here's output for a query that had some trouble - nodes didn't respond and speculative execution decided to query others in parallel. +Finally the third node provided a response. +```none +=== Query #0 === +| start_time: 2022-08-26 15:08:28.525367409 UTC +| Non-speculative attempts: +| - Attempt #0 sent to 127.0.0.219:9042 +| request send time: 2022-08-26 15:08:28.525409294 UTC +| No result yet +| +| +| > Speculative fiber #0 +| fiber start time: 2022-08-26 15:08:28.537074167 UTC +| - Attempt #0 sent to 127.0.0.217:9042 +| request send time: 2022-08-26 15:08:28.537126083 UTC +| No result yet +| +| +| > Speculative fiber #1 +| fiber start time: 2022-08-26 15:08:28.548050242 UTC +| - Attempt #0 sent to 127.0.0.218:9042 +| request send time: 2022-08-26 15:08:28.548089083 UTC +| Success at 2022-08-26 15:08:28.590052778 UTC +| +| Query successful at 2022-08-26 15:08:28.590078119 UTC +================= +``` + +## How the driver executes queries + +To read the output it's useful to understand more about how the driver executes queries. + +### No speculative execution +Without speculative execution the driver performs many attempts sequentially until one of them succeeds. +A single attempt consists of sending a request to some node and waiting for the answer. +In case of an error the driver consults the retry policy to decide what to do next. +The decision might be to fail the query, retry on the same node, another node, change query parameters, etc. +Once the decision is made either the query fails or another attempt is started. This continues until the query ends. + +### Speculative execution +When speculative execution is enabled at first the driver doesn't care about it - it does the attempts sequentially and tries to get an answer. +However once a specified amount of time has passed it will decide to try new attempts in parallel +hoping that another node will be able to answer quicker. +This is done by spawning a speculative fiber. Each spawned fiber performs sequential attempts just like in non-speculative execution. +Many fibers can be spawned if the answer wasn't acquired in time. + +### StructuredHistory +[`StructuredHistory`](https://docs.rs/scylla/latest/scylla/history/struct.StructuredHistory.html) +is a history representation that represents the history by listing attempts for each speculative fiber. + +## HistoryListener trait, custom history collecting + +History can be collected by any struct implementing the +[`HistoryListener`](https://docs.rs/scylla/latest/scylla/history/trait.HistoryListener.html) trait. + +The implementation of `HistoryListener` provided by this crate is the +[`HistoryCollector`](https://docs.rs/scylla/latest/scylla/history/struct.HistoryCollector.html). +`HistoryCollector` simply collects all events along with their timestamps. + +Information collected by `HistoryCollector` is just a stream of events, in order to analyze it it's possible +to convert it to a structured representation. +[`StructuredHistory`](https://docs.rs/scylla/latest/scylla/history/struct.StructuredHistory.html) +can be created by calling `HistoryCollector::clone_structured_history()`. diff --git a/stable/_sources/tracing/tracing.md.txt b/stable/_sources/tracing/tracing.md.txt new file mode 100644 index 0000000000..75ea2d5fee --- /dev/null +++ b/stable/_sources/tracing/tracing.md.txt @@ -0,0 +1,41 @@ +# Query tracing + +The driver has utilities for monitoring the execution of queries. +There are two separate ways to get information about what happened with a query: `Tracing` and `Query Execution History`. + +### Tracing + +Tracing is a feature provided by Scylla. When sending a query we can set a flag that signifies that we would like it to be traced. +After completing the query Scylla provides a `tracing_id` which can be used to fetch information about it - which nodes it was sent to, what operations were performed etc. + +Queries that support tracing: +* [`Session::query()`](basic.md) +* [`Session::query_iter()`](paged.md) +* [`Session::execute()`](basic.md) +* [`Session::execute_iter()`](paged.md) +* [`Session::batch()`](basic.md) +* [`Session::prepare()`](prepare.md) + +After obtaining the tracing id you can use `Session::get_tracing_info()` to query tracing information.\ +`TracingInfo` contains values that are the same in Scylla and Cassandra®, skipping any database-specific ones.\ +If `TracingInfo` does not contain some needed value it's possible to query it manually from the tables +`system_traces.sessions` and `system_traces.events` + +### Query Execution History + +Tracing provides information about how the query execution went on database nodes, but it doesn't say anything about what was going on inside the driver.\ +This is what query execution history was made for. + +It allows to follow what the driver was thinking - all query attempts, retry decisions, speculative executions. +More information is available in the [Query Execution History](query-history.md) chapter. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + basic + paged + prepare + query-history +``` \ No newline at end of file diff --git a/stable/_static/basic.css b/stable/_static/basic.css new file mode 100644 index 0000000000..30fee9d0f7 --- /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 0000000000..92fad4b5c0 --- /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 0000000000..54b3c46381 --- /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 0000000000..f1916ec7d1 --- /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 0000000000..2ea7ff3e21 --- /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 0000000000..dbe1aaad79 --- /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 0000000000..65eb0a5536 --- /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 0000000000..d06a71d751 --- /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 0000000000..7e4c114f21 --- /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 0000000000..a858a410e4 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 0000000000..f8520d5b3e --- /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 0000000000..f30770c7ed 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 0000000000..aae1708f26 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 0000000000..6c7484f082 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 0000000000..5448c7f007 --- /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 0000000000..09107d9520 --- /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 0000000000..1b1fcc83e3 --- /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 0000000000..7c2b4ebae0 --- /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 0000000000..7e93612026 --- /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 0000000000..67ebbc2f38 --- /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 0000000000..e1ce2c1d78 --- /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 0000000000..f4096cbf11 --- /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 0000000000..2a7c6ea0b7 --- /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 0000000000..3afa25c481 --- /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 0000000000..44eb829cdc --- /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 0000000000..875e421670 --- /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 0000000000..8c92469808 --- /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 0000000000..d1162b73e7 --- /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 0000000000..a9069bb6e5 --- /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 0000000000..cfb2318dae --- /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 0000000000..49d809a5df --- /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 0000000000..9df3145dd2 --- /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 0000000000..ee804197a0 --- /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 0000000000..5501492f3e --- /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 0000000000..97be900b50 --- /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 0000000000..ee1ac26283 --- /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 0000000000..ba5f211864 --- /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 0000000000..a7eb4b77a4 --- /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 0000000000..3806565367 --- /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 0000000000..37a709f7a8 --- /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 0000000000..702500be40 --- /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 0000000000..e8329c2afe --- /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 0000000000..f0b9c25419 --- /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 0000000000..906e87279c --- /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 0000000000..1ef0920d49 --- /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 0000000000..884451270d --- /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 0000000000..3094127dec --- /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 0000000000..dcb5916c26 --- /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 0000000000..0e6192a352 --- /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 0000000000..02b4e425be --- /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 0000000000..e34eb4504f --- /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 0000000000..97fa3a0e21 --- /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 0000000000..80b3787f66 --- /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 0000000000..40a3fd5f6f --- /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 0000000000..a952b59937 --- /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 0000000000..5b8d47eb15 --- /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 0000000000..60ebab3795 --- /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 0000000000..98c2ea7d5b --- /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 0000000000..bb7d8d3ea8 --- /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 0000000000..515c1528a2 --- /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 0000000000..d0146fc497 --- /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 0000000000..5757435085 --- /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 0000000000..74b01db168 --- /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 0000000000..80c490c7b0 --- /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 0000000000..6e3ab08e79 --- /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 0000000000..c8cbf67c8c --- /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 0000000000..81aae93eef --- /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 0000000000..fc164ea1e7 --- /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 0000000000..bebe9b8274 --- /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 0000000000..4b900bd0c0 --- /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 0000000000..a4228b34e8 --- /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 0000000000..df42b5522b --- /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 0000000000..2fe54efdbc --- /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 0000000000..3e7bcd6d90 --- /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 0000000000..226c44d853 --- /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 0000000000..bf7aa6af84 --- /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 0000000000..08b95a88ed --- /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 0000000000..e8ae088106 --- /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 0000000000..f7547ab959 --- /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 0000000000..47e56cddcf --- /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 0000000000..e4b1d40331 --- /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 0000000000..5e9f5cd427 --- /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 0000000000..3351e51d23 --- /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 0000000000..5206e58e98 --- /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 0000000000..4fff669cb6 --- /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 0000000000..b5022d7c4d --- /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 0000000000..769fa0889f 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 0000000000..7c06d01674 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 0000000000..d33fddd62f 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 0000000000..0462f893d5 --- /dev/null +++ b/stable/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/stable/_static/img/mascots/scylla-cloud.svg b/stable/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 0000000000..a6c6a26fc9 --- /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 0000000000..d0368a7027 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 0000000000..0cdadaa216 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 0000000000..e889f4e368 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 0000000000..a5bce950c2 --- /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 0000000000..6012e71679 --- /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 0000000000..a1aa0b46ac --- /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 0000000000..f64c29e6c7 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 0000000000..d2f645c645 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 0000000000..0f53b26afa 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 0000000000..630f2d9094 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 0000000000..c87abe684d 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 0000000000..ba52cd223d 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 0000000000..cef08c8654 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 0000000000..75cccbfdf1 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 0000000000..6f10405f21 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 0000000000..e368cae169 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 0000000000..74ad669500 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 0000000000..6ba9ed937c --- /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 0000000000..48bec7dde3 --- /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 0000000000..956d1dd0e2 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 0000000000..7ee2b04338 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 0000000000..3b2dc8f1a2 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 0000000000..299e9cb995 --- /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 0000000000..655a450b2a --- /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 0000000000..b28dc857cc 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 0000000000..09342ac687 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 0000000000..9b4c613e70 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 0000000000..96dc785298 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 0000000000..f88598e05a 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 0000000000..6f0ca146c0 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 0000000000..b3d0621193 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 0000000000..b070bb022c 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 0000000000..6a8b16a6b4 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 0000000000..f3b8b2984f 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 0000000000..b38a6fbbe0 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 0000000000..954bf13bc2 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 0000000000..d35a13d380 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 0000000000..30ea1d901e --- /dev/null +++ b/stable/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/stable/_static/js/main.bundle.js b/stable/_static/js/main.bundle.js new file mode 100644 index 0000000000..190a41642e --- /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 +
        +
        +
        +
        +
        + + + + + + +
        +

        Authentication

        +

        Driver supports both authentication by username and password and custom authentication defined by a user.

        + +
        +

        Custom Authentication

        +

        A custom authentication is defined by implementing the AuthenticatorSession. +An AuthenticatorSession instance is created per session, so it is also necessary to define a AuthenticatorProvider for it. +Finally, to make use of the custom authentication, use the authenticator_provider method in SessionBuilder:

        +
        use bytes::{BufMut, BytesMut};
        +use async_trait::async_trait;
        +use scylla::authentication::{AuthError, AuthenticatorProvider, AuthenticatorSession};
        +
        +struct CustomAuthenticator;
        +
        +#[async_trait]
        +impl AuthenticatorSession for CustomAuthenticator {
        +    // to handle an authentication challenge initiated by the server.
        +    // The information contained in the token parameter is authentication protocol specific.
        +    // It may be NULL or empty. 
        +    async fn evaluate_challenge(
        +        &mut self,
        +        _token: Option<&[u8]>,
        +    ) -> Result<Option<Vec<u8>>, AuthError> {
        +        Err("Challenges are not expected".to_string())
        +    }
        +
        +    // to handle the success phase of exchange. The token parameters contain information that may be used to finalize the request.
        +    async fn success(&mut self, _token: Option<&[u8]>) -> Result<(), AuthError> {
        +        Ok(())
        +    }
        +}
        +
        +struct CustomAuthenticatorProvider;
        +
        +#[async_trait]
        +impl AuthenticatorProvider for CustomAuthenticatorProvider {
        +    async fn start_authentication_session(
        +        &self,
        +        _name: &str,
        +    ) -> Result<(Option<Vec<u8>>, Box<dyn AuthenticatorSession>), AuthError> {
        +        let mut response = BytesMut::new();
        +        let cred = "\0cassandra\0cassandra";
        +        let cred_length = 20;
        +
        +        response.put_i32(cred_length);
        +        response.put_slice(cred.as_bytes());
        +
        +        Ok((Some(response.to_vec()), Box::new(CustomAuthenticator)))
        +    }
        +}
        +
        +async fn authentication_example() -> Result<(), Box<dyn Error>> {
        +    use scylla::{Session, SessionBuilder};
        +
        +    let _session: Session = SessionBuilder::new()
        +        .known_node("127.0.0.1:9042")
        +        .authenticator_provider(Arc::new(CustomAuthenticatorProvider))
        +        .build()
        +        .await?;
        +
        +    Ok(())
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/connecting/compression.html b/stable/connecting/compression.html new file mode 100644 index 0000000000..f32a0e8f9e --- /dev/null +++ b/stable/connecting/compression.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Compression | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Compression

        +

        By default the driver does not use any compression on connections.
        +It’s possible to specify a preferred compression algorithm.
        +The driver will try using it, but if the database doesn’t support it, it will fall back to no compression.

        +

        Available compression algorithms:

        +
          +
        • Snappy

        • +
        • LZ4

        • +
        +

        An example enabling Snappy compression algorithm:

        +
        use scylla::{Session, SessionBuilder};
        +use scylla::transport::Compression;
        +use std::error::Error;
        +
        +#[tokio::main]
        +async fn main() -> Result<(), Box<dyn Error>> {
        +    let uri = std::env::var("SCYLLA_URI")
        +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
        +
        +    let session: Session = SessionBuilder::new()
        +        .known_node(uri)
        +        .compression(Some(Compression::Snappy))
        +        .build()
        +        .await?;
        +
        +    Ok(())
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/connecting/connecting.html b/stable/connecting/connecting.html new file mode 100644 index 0000000000..ff832e85a5 --- /dev/null +++ b/stable/connecting/connecting.html @@ -0,0 +1,709 @@ + + + + + + + + + + + + + Connecting to the cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Connecting to the cluster

        +

        Scylla is a distributed database, which means that it operates on multiple nodes running independently. +When creating a Session you can specify a few known nodes to which the driver will try connecting:

        +
        use scylla::{Session, SessionBuilder};
        +use std::error::Error;
        +use std::time::Duration;
        +use std::net::{IpAddr, Ipv4Addr, SocketAddr};
        +
        +#[tokio::main]
        +async fn main() -> Result<(), Box<dyn Error>> {
        +    let uri = std::env::var("SCYLLA_URI")
        +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
        +
        +    let session: Session = SessionBuilder::new()
        +        .known_node(uri)
        +        .known_node("127.0.0.72:4321")
        +        .known_node("localhost:8000")
        +        .connection_timeout(Duration::from_secs(3))
        +        .cluster_metadata_refresh_interval(Duration::from_secs(10))
        +        .known_node_addr(SocketAddr::new(
        +            IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
        +            9000,
        +        ))
        +        .build()
        +        .await?;
        +
        +    Ok(())
        +}
        +
        +
        +

        After successfully connecting to some specified node the driver will fetch topology information about +other nodes in this cluster and connect to them as well.

        +
        +

        Best practices for using Session

        +
        +

        Warning

        +

        Always try to use only a single Session object per apllication because creating them is very expensive!

        +
        +

        The driver maintains its own pool of connections to each node and each connection is capable of handling multiple requests in parallel. Driver will also route requests to nodes / shards that actually own the data (unless the load balancing policy that you use doesn’t support it).

        +

        For those reasons, we recommend using one instance of Session per application.

        +

        Creating short-lived Session’s (e.g. Session per request) is strongly discouraged because it will result in great performance penalties because creating a Session is a costly process - it requires estabilishing a lot of TCP connections. +Creating many Session’s in one application (e.g. Session per thread / per Tokio task) is also discouraged, because it wastes resources - as mentioned before, Session maintains a connection pool itself and can handle parallel queries, so you would be holding a lot of connections unnecessarily.

        +

        If you need to share Session with different threads / Tokio tasks etc. use Arc<Session> - all methods of Session take &self, so it doesn’t hinder the functionality in any way.

        +
        +
        +

        Metadata

        +

        The driver refreshes the cluster metadata periodically, which contains information about cluster topology as well as the cluster schema. By default, the driver refreshes the cluster metadata every 60 seconds. +However, you can set the cluster_metadata_refresh_interval to a non-negative value to periodically refresh the cluster metadata. This is useful when you do not have unexpected amount of traffic or when you have an extra traffic causing topology to change frequently.

        +
        +
        +

        Scylla Cloud Serverless

        +

        Scylla Serverless is an elastic and dynamic deployment model. When creating a Session you need to +specify the secure connection bundle as follows:

        +
        use std::path::Path;
        +use std::error::Error;
        +use scylla::CloudSessionBuilder;
        +
        +#[tokio::main]
        +async fn main() -> Result<(), Box<dyn Error>> {
        +    let session = CloudSessionBuilder::new(Path::new("config_data.yaml"))
        +        .unwrap()
        +        .build()
        +        .await
        +        .unwrap();
        +
        +    Ok(())
        +}
        +
        +
        +

        Note that the bundle file will be provided after the serverless cluster is created. Here is an example of a +configuration file for a serverless cluster:

        +
        datacenters:
        +  datacenter1:
        +    certificateAuthorityData: CERTIFICATE_DATA
        +    server: 127.0.1.1:9142
        +    nodeDomain: cql.cluster-id.scylla.com
        +    insecureSkipTlsVerify: false
        +authInfos:
        +  default:
        +    clientCertificateData: CERTIFICATE_DATA
        +    clientKeyData: KEY_DATA
        +    username: scylladb
        +    password: scylladb
        +contexts:
        +  default:
        +    datacenterName: datacenter1
        +    authInfoName: default
        +currentContext: default
        +
        +
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/connecting/tls.html b/stable/connecting/tls.html new file mode 100644 index 0000000000..37c35b1eef --- /dev/null +++ b/stable/connecting/tls.html @@ -0,0 +1,686 @@ + + + + + + + + + + + + + TLS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        TLS

        +

        Driver uses the openssl crate for TLS functionality.
        +It was chosen because rustls doesn’t support certificates for ip addresses +(see issue), which is a common use case for Scylla.

        +
        +

        Enabling feature

        +

        openssl is not a pure Rust library so you need enable a feature and install the proper package.

        +

        To enable the tls feature add in Cargo.toml:

        +
        scylla = { version = "0.4", features = ["ssl"] }
        +openssl = "0.10.32"
        +
        +
        +

        Then install the package with openssl:

        +
          +
        • Debian/Ubuntu:

          +
          apt install libssl-dev pkg-config
          +
          +
          +
        • +
        • Fedora:

          +
          dnf install openssl-devel
          +
          +
          +
        • +
        + +
          +
        • Arch:

          +
          pacman -S openssl pkg-config
          +
          +
          +
        • +
        +
        +
        +

        Using TLS

        +

        To use tls you will have to create an openssl +SslContext +and pass it to SessionBuilder

        +

        For example, if database certificate is in the file ca.crt:

        +
        use scylla::{Session, SessionBuilder};
        +use openssl::ssl::{SslContextBuilder, SslMethod, SslVerifyMode};
        +use std::path::PathBuf;
        +
        +let mut context_builder = SslContextBuilder::new(SslMethod::tls())?;
        +context_builder.set_ca_file("ca.crt")?;
        +context_builder.set_verify(SslVerifyMode::PEER);
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9142") // The the port is now 9142
        +    .ssl_context(Some(context_builder.build()))
        +    .build()
        +    .await?;
        +
        +
        +

        See the full example for more details

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/contents.html b/stable/contents.html new file mode 100644 index 0000000000..26abbcb835 --- /dev/null +++ b/stable/contents.html @@ -0,0 +1,599 @@ + + + + + + + + + + + + + <no title> | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/blob.html b/stable/data-types/blob.html new file mode 100644 index 0000000000..bca667d347 --- /dev/null +++ b/stable/data-types/blob.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + + Blob | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Blob

        +

        Blob is represented as Vec<u8>

        +
        use scylla::IntoTypedRows;
        +
        +// Insert some blob into the table as a Vec<u8>
        +// We can insert it by reference to not move the whole blob
        +let to_insert: Vec<u8> = vec![1, 2, 3, 4, 5];
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&to_insert,))
        +    .await?;
        +
        +// Read blobs from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(Vec<u8>,)>()?;
        +while let Some((blob_value,)) = iter.next().transpose()? {
        +    println!("{:?}", blob_value);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/collections.html b/stable/data-types/collections.html new file mode 100644 index 0000000000..e7a5f79860 --- /dev/null +++ b/stable/data-types/collections.html @@ -0,0 +1,739 @@ + + + + + + + + + + + + + List, Set, Map | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        List, Set, Map

        +
        +

        List

        +

        List is represented as Vec<T>

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a list of ints into the table
        +let my_list: Vec<i32> = vec![1, 2, 3, 4, 5];
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_list,))
        +    .await?;
        +
        +// Read a list of ints from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(Vec<i32>,)>()?;
        +while let Some((list_value,)) = iter.next().transpose()? {
        +    println!("{:?}", list_value);
        +}
        +
        +
        +
        +
        +

        Set

        +

        Set is represented as Vec<T>, HashSet<T> or BTreeSet<T>:

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a set of ints into the table
        +let my_set: Vec<i32> = vec![1, 2, 3, 4, 5];
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
        +    .await?;
        +
        +// Read a set of ints from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(Vec<i32>,)>()?;
        +while let Some((list_value,)) = iter.next().transpose()? {
        +    println!("{:?}", list_value);
        +}
        +
        +
        +
        use scylla::IntoTypedRows;
        +use std::collections::HashSet;
        +
        +// Insert a set of ints into the table
        +let my_set: HashSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
        +    .await?;
        +
        +// Read a set of ints from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(HashSet<i32>,)>()?;
        +while let Some((list_value,)) = iter.next().transpose()? {
        +    println!("{:?}", list_value);
        +}
        +
        +
        +
        use scylla::IntoTypedRows;
        +use std::collections::BTreeSet;
        +
        +// Insert a set of ints into the table
        +let my_set: BTreeSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
        +    .await?;
        +
        +// Read a set of ints from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(BTreeSet<i32>,)>()?;
        +while let Some((list_value,)) = iter.next().transpose()? {
        +    println!("{:?}", list_value);
        +}
        +
        +
        +
        +
        +

        Map

        +

        Map is represented as HashMap<K, V> or BTreeMap<K, V>

        +
        use scylla::IntoTypedRows;
        +use std::collections::HashMap;
        +
        +// Insert a map of text and int into the table
        +let mut my_map: HashMap<String, i32> = HashMap::new();
        +my_map.insert("abcd".to_string(), 16);
        +
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,))
        +    .await?;
        +
        +// Read a map from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(HashMap<String, i32>,)>()?;
        +while let Some((map_value,)) = iter.next().transpose()? {
        +    println!("{:?}", map_value);
        +}
        +
        +
        +
        use scylla::IntoTypedRows;
        +use std::collections::BTreeMap;
        +
        +// Insert a map of text and int into the table
        +let mut my_map: BTreeMap<String, i32> = BTreeMap::new();
        +my_map.insert("abcd".to_string(), 16);
        +
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,))
        +    .await?;
        +
        +// Read a map from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(BTreeMap<String, i32>,)>()?;
        +while let Some((map_value,)) = iter.next().transpose()? {
        +    println!("{:?}", map_value);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/counter.html b/stable/data-types/counter.html new file mode 100644 index 0000000000..eea9f028bf --- /dev/null +++ b/stable/data-types/counter.html @@ -0,0 +1,624 @@ + + + + + + + + + + + + + Counter | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Counter

        +

        Counter is represented as struct Counter(pub i64)
        +Counter can’t be inserted, it can only be read or updated.

        +
        use scylla::IntoTypedRows;
        +use scylla::frame::value::Counter;
        +
        +// Read counter from the table
        +let result = session.query("SELECT c FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(Counter,)>()?;
        +while let Some((counter_value,)) = iter.next().transpose()? {
        +    let counter_int_value: i64 = counter_value.0;
        +    println!("{}", counter_int_value);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/data-types.html b/stable/data-types/data-types.html new file mode 100644 index 0000000000..3360a9b291 --- /dev/null +++ b/stable/data-types/data-types.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Data Types | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Data Types

        +

        The driver maps database data types to matching Rust types +to achieve seamless sending and receiving of CQL values.

        +

        See the following chapters for examples on how to send and receive each data type.

        +

        See Query values for more information about sending values in queries.
        +See Query result for more information about reading values from queries

        +

        Database types and their Rust equivalents:

        +
          +
        • Boolean <—-> bool

        • +
        • Tinyint <—-> i8

        • +
        • Smallint <—-> i16

        • +
        • Int <—-> i32

        • +
        • BigInt <—-> i64

        • +
        • Float <—-> f32

        • +
        • Double <—-> f64

        • +
        • Ascii, Text, Varchar <—-> &str, String

        • +
        • Counter <—-> value::Counter

        • +
        • Blob <—-> Vec<u8>

        • +
        • Inet <—-> std::net::IpAddr

        • +
        • Uuid <—-> uuid::Uuid

        • +
        • Timeuuid <—-> value::CqlTimeuuid

        • +
        • Date <—-> value::CqlDate, chrono::NaiveDate, time::Date

        • +
        • Time <—-> value::CqlTime, chrono::NaiveTime, time::Time

        • +
        • Timestamp <—-> value::CqlTimestamp, chrono::DateTime<Utc>, time::OffsetDateTime

        • +
        • Duration <—-> value::CqlDuration

        • +
        • Decimal <—-> value::CqlDecimal, bigdecimal::Decimal

        • +
        • Varint <—-> value::CqlVarint, num_bigint::BigInt (v0.3 and v0.4)

        • +
        • List <—-> Vec<T>

        • +
        • Set <—-> Vec<T>

        • +
        • Map <—-> std::collections::HashMap<K, V>

        • +
        • Tuple <—-> Rust tuples

        • +
        • UDT (User defined type) <—-> Custom user structs with macros

        • +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/date.html b/stable/data-types/date.html new file mode 100644 index 0000000000..4b81c513b0 --- /dev/null +++ b/stable/data-types/date.html @@ -0,0 +1,707 @@ + + + + + + + + + + + + + Date | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Date

        +

        Depending on feature flags, three different types can be used to interact with date.

        +

        Internally date is represented as number of days since +-5877641-06-23 i.e. 2^31 days before unix epoch.

        +
        +

        CqlDate

        +

        Without any extra features enabled, only frame::value::CqlDate is available. It’s an +u32 wrapper and it matches the internal date representation.

        +

        However, for most use cases other types are more practical. See following sections for chrono and time.

        +
        use scylla::frame::value::CqlDate;
        +use scylla::IntoTypedRows;
        +
        +// 1970-01-08
        +let to_insert = CqlDate((1 << 31) + 7);
        +
        +// Insert date into the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read raw Date from the table
        +if let Some(rows) = session
        +    .query("SELECT a FROM keyspace.table", &[])
        +    .await?
        +    .rows
        +{
        +    for row in rows.into_typed::<(CqlDate,)>() {
        +        let (date_value,): (CqlDate,) = row?;
        +    }
        +}
        +
        +
        +
        +
        +

        chrono::NaiveDate

        +

        If full range is not required and chrono feature is enabled, +chrono::NaiveDate can be used. +chrono::NaiveDate supports dates from +-262145-01-01 to 262143-12-31.

        +
        use chrono::NaiveDate;
        +use scylla::IntoTypedRows;
        +
        +// 2021-03-24
        +let to_insert = NaiveDate::from_ymd_opt(2021, 3, 24).unwrap();
        +
        +// Insert date into the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read NaiveDate from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(NaiveDate,)>()?;
        +while let Some((date_value,)) = iter.next().transpose()? {
        +    println!("{:?}", date_value);
        +}
        +
        +
        +
        +
        +

        time::Date

        +

        Alternatively, time feature can be used to enable support of +time::Date. +time::Date’s value range depends on feature flags, see its +documentation to get more info.

        +
        use scylla::IntoTypedRows;
        +use time::{Date, Month};
        +
        +// 2021-03-24
        +let to_insert = Date::from_calendar_date(2021, Month::March, 24).unwrap();
        +
        +// Insert date into the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read Date from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(Date,)>()?;
        +while let Some((date_value,)) = iter.next().transpose()? {
        +    println!("{:?}", date_value);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/decimal.html b/stable/data-types/decimal.html new file mode 100644 index 0000000000..e919a18d94 --- /dev/null +++ b/stable/data-types/decimal.html @@ -0,0 +1,668 @@ + + + + + + + + + + + + + Decimal | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Decimal

        +

        Decimal is represented as value::CqlDecimal or bigdecimal::BigDecimal

        +
        +

        value::CqlDecimal

        +

        Without any feature flags, the user can interact with decimal type by making use of value::CqlDecimal which is a very simple wrapper representing the value as signed binary number in big-endian order with a 32-bit scale.

        +
        use scylla::IntoTypedRows;
        +use scylla::frame::value::CqlDecimal;
        +use std::str::FromStr;
        +
        +// Insert a decimal (123.456) into the table
        +let to_insert: CqlDecimal =
        +        CqlDecimal::from_signed_be_bytes_and_exponent(vec![0x01, 0xE2, 0x40], 3);
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a decimal from the table
        +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
        +    for row in rows.into_typed::<(CqlDecimal,)>() {
        +        let (decimal_value,): (CqlDecimal,) = row?;
        +    }
        +}
        +
        +
        +
        +
        +

        bigdecimal::BigDecimal

        +

        To make use of bigdecimal::Bigdecimal type, user should enable bigdecimal-04 crate feature.

        +
        use scylla::IntoTypedRows;
        +use bigdecimal::BigDecimal;
        +use std::str::FromStr;
        +
        +// Insert a decimal into the table
        +let to_insert: BigDecimal = BigDecimal::from_str("12345.0")?;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a decimal from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(BigDecimal,)>()?;
        +while let Some((decimal_value,)) = iter.next().transpose()? {
        +    println!("{:?}", decimal_value);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/duration.html b/stable/data-types/duration.html new file mode 100644 index 0000000000..d96434c6dd --- /dev/null +++ b/stable/data-types/duration.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + + Duration | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Duration

        +

        Duration is represented as CqlDuration\

        +
        use scylla::IntoTypedRows;
        +use scylla::frame::value::CqlDuration;
        +
        +// Insert some duration into the table
        +let to_insert: CqlDuration = CqlDuration { months: 1, days: 2, nanoseconds: 3 };
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read duration from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(CqlDuration,)>()?;
        +while let Some((duration_value,)) = iter.next().transpose()? {
        +    println!("{:?}", duration_value);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/inet.html b/stable/data-types/inet.html new file mode 100644 index 0000000000..601e23324d --- /dev/null +++ b/stable/data-types/inet.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + + Inet | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Inet

        +

        Inet is represented as std::net::IpAddr

        +
        use scylla::IntoTypedRows;
        +use std::net::{IpAddr, Ipv4Addr};
        +
        +// Insert some ip address into the table
        +let to_insert: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read inet from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(IpAddr,)>()?;
        +while let Some((inet_value,)) = iter.next().transpose()? {
        +    println!("{:?}", inet_value);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/primitive.html b/stable/data-types/primitive.html new file mode 100644 index 0000000000..7d654757b2 --- /dev/null +++ b/stable/data-types/primitive.html @@ -0,0 +1,767 @@ + + + + + + + + + + + + + Bool, Tinyint, Smallint, Int, Bigint, Float, Double | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Bool, Tinyint, Smallint, Int, Bigint, Float, Double

        +
        +

        Bool

        +

        Bool is represented as rust bool

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a bool into the table
        +let to_insert: bool = true;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a bool from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(bool,)>()?;
        +while let Some((bool_value,)) = iter.next().transpose()? {
        +    println!("{}", bool_value);
        +}
        +
        +
        +
        +
        +

        Tinyint

        +

        Tinyint is represented as rust i8

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a tinyint into the table
        +let to_insert: i8 = 123;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a tinyint from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(i8,)>()?;
        +while let Some((tinyint_value,)) = iter.next().transpose()? {
        +    println!("{:?}", tinyint_value);
        +}
        +
        +
        +
        +
        +

        Smallint

        +

        Smallint is represented as rust i16

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a smallint into the table
        +let to_insert: i16 = 12345;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a smallint from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(i16,)>()?;
        +while let Some((smallint_value,)) = iter.next().transpose()? {
        +    println!("{}", smallint_value);
        +}
        +
        +
        +
        +
        +

        Int

        +

        Int is represented as rust i32

        +
        use scylla::IntoTypedRows;
        +
        +// Insert an int into the table
        +let to_insert: i32 = 12345;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read an int from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(i32,)>()?;
        +while let Some((int_value,)) = iter.next().transpose()? {
        +    println!("{}", int_value);
        +}
        +
        +
        +
        +
        +

        Bigint

        +

        Bigint is represented as rust i64

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a bigint into the table
        +let to_insert: i64 = 12345;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a bigint from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(i64,)>()?;
        +while let Some((bigint_value,)) = iter.next().transpose()? {
        +    println!("{:?}", bigint_value);
        +}
        +
        +
        +
        +
        +

        Float

        +

        Float is represented as rust f32

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a float into the table
        +let to_insert: f32 = 123.0;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a float from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(f32,)>()?;
        +while let Some((float_value,)) = iter.next().transpose()? {
        +    println!("{:?}", float_value);
        +}
        +
        +
        +
        +
        +

        Double

        +

        Double is represented as rust f64

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a double into the table
        +let to_insert: f64 = 12345.0;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a double from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(f64,)>()?;
        +while let Some((double_value,)) = iter.next().transpose()? {
        +    println!("{:?}", double_value);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/text.html b/stable/data-types/text.html new file mode 100644 index 0000000000..d0a880793a --- /dev/null +++ b/stable/data-types/text.html @@ -0,0 +1,633 @@ + + + + + + + + + + + + + Ascii, Text, Varchar | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Ascii, Text, Varchar

        +

        Ascii, Text and Varchar are represented as &str and String

        +
        use scylla::IntoTypedRows;
        +
        +// Insert some text into the table as a &str
        +let to_insert_str: &str = "abcdef";
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_str,))
        +    .await?;
        +
        +// Insert some text into the table as a String
        +let to_insert_string: String = "abcdef".to_string();
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_string,))
        +    .await?;
        +
        +// Read ascii/text/varchar from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(String,)>()?;
        +while let Some((text_value,)) = iter.next().transpose()? {
        +    println!("{}", text_value);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/time.html b/stable/data-types/time.html new file mode 100644 index 0000000000..0cdcc4f4d5 --- /dev/null +++ b/stable/data-types/time.html @@ -0,0 +1,705 @@ + + + + + + + + + + + + + Time | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Time

        +

        Depending on feature flags used, three different types can be used to interact with time.

        +

        Internally time is represented as number of nanoseconds since +midnight. It can’t be negative or exceed 86399999999999 (23:59:59.999999999).

        +
        +

        CqlTime

        +

        Without any extra features enabled, only frame::value::CqlTime is available. It’s an +i64 wrapper and it matches the internal time representation.

        +

        However, for most use cases other types are more practical. See following sections for chrono and time.

        +
        use scylla::frame::value::CqlTime;
        +use scylla::IntoTypedRows;
        +
        +// 64 seconds since midnight
        +let to_insert = CqlTime(64 * 1_000_000_000);
        +
        +// Insert time into the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read time from the table
        +if let Some(rows) = session
        +    .query("SELECT a FROM keyspace.table", &[])
        +    .await?
        +    .rows
        +{
        +    for row in rows.into_typed::<(CqlTime,)>() {
        +        let (time_value,): (CqlTime,) = row?;
        +    }
        +}
        +
        +
        +
        +
        +

        chrono::NaiveTime

        +

        If chrono feature is enabled, chrono::NaiveTime +can be used to interact with the database. Although chrono can represent leap seconds, they are not supported. +Attempts to convert chrono::NaiveTime with leap +second to CqlTime or write it to the database will return an error.

        +
        use chrono::NaiveTime;
        +use scylla::IntoTypedRows;
        +
        +// 01:02:03.456,789,012
        +let to_insert = NaiveTime::from_hms_nano_opt(1, 2, 3, 456_789_012);
        +
        +// Insert time into the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read time from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(NaiveTime,)>()?;
        +while let Some((time_value,)) = iter.next().transpose()? {
        +    println!("{:?}", time_value);
        +}
        +
        +
        +
        +
        +

        time::Time

        +

        If time feature is enabled, time::Time can be used to interact +with the database.

        +
        use scylla::IntoTypedRows;
        +use time::Time;
        +
        +// 01:02:03.456,789,012
        +let to_insert = Time::from_hms_nano(1, 2, 3, 456_789_012).unwrap();
        +
        +// Insert time into the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read time from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(Time,)>()?;
        +while let Some((time_value,)) = iter.next().transpose()? {
        +    println!("{:?}", time_value);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/timestamp.html b/stable/data-types/timestamp.html new file mode 100644 index 0000000000..b61b0d581c --- /dev/null +++ b/stable/data-types/timestamp.html @@ -0,0 +1,717 @@ + + + + + + + + + + + + + Timestamp | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Timestamp

        +

        Depending on feature flags, three different types can be used to interact with timestamps.

        +

        Internally timestamp is represented as +i64 describing number of milliseconds since unix epoch.

        +
        +

        CqlTimestamp

        +

        Without any extra features enabled, only frame::value::CqlTimestamp is available. It’s an +i64 wrapper and it matches the internal time representation. It’s +the only type that supports full range of values that database accepts.

        +

        However, for most use cases other types are more practical. See following sections for chrono and time.

        +
        use scylla::frame::value::CqlTimestamp;
        +use scylla::IntoTypedRows;
        +
        +// 64 seconds since unix epoch, 1970-01-01 00:01:04
        +let to_insert = CqlTimestamp(64 * 1000);
        +
        +// Write timestamp to the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read timestamp from the table
        +if let Some(rows) = session
        +    .query("SELECT a FROM keyspace.table", &[])
        +    .await?
        +    .rows
        +{
        +    for row in rows.into_typed::<(CqlTimestamp,)>() {
        +        let (timestamp_value,): (CqlTimestamp,) = row?;
        +    }
        +}
        +
        +
        +
        +
        +

        chrono::DateTime

        +

        If full value range is not required, chrono feature can be used to enable support of +chrono::DateTime. All values are expected to be converted +to UTC timezone explicitly, as timestamp doesn’t store +timezone information. Any precision finer than 1ms will be lost.

        +
        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
        +use scylla::IntoTypedRows;
        +
        +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123
        +let to_insert = NaiveDateTime::new(
        +    NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(),
        +    NaiveTime::from_hms_milli_opt(0, 1, 4, 123).unwrap(),
        +)
        +.and_utc();
        +
        +// Write timestamp to the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read timestamp from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(DateTime<Utc>,)>()?;
        +while let Some((timestamp_value,)) = iter.next().transpose()? {
        +    println!("{:?}", timestamp_value);
        +}
        +
        +
        +
        +
        +

        time::OffsetDateTime

        +

        Alternatively, time feature can be used to enable support of +time::OffsetDateTime. As +timestamp doesn’t support timezone information, time will +be corrected to UTC and timezone info will be erased on write. On read, UTC timestamp is returned. Any precision finer +than 1ms will also be lost.

        +
        use scylla::IntoTypedRows;
        +use time::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time};
        +
        +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123
        +let to_insert = PrimitiveDateTime::new(
        +    Date::from_calendar_date(1970, Month::January, 1).unwrap(),
        +    Time::from_hms_milli(0, 1, 4, 123).unwrap(),
        +)
        +.assume_utc();
        +
        +// Write timestamp to the table
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read timestamp from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(OffsetDateTime,)>()?;
        +while let Some((timestamp_value,)) = iter.next().transpose()? {
        +    println!("{:?}", timestamp_value);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/timeuuid.html b/stable/data-types/timeuuid.html new file mode 100644 index 0000000000..3eaab02c7b --- /dev/null +++ b/stable/data-types/timeuuid.html @@ -0,0 +1,630 @@ + + + + + + + + + + + + + Timeuuid | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Timeuuid

        +

        Timeuuid is represented as value::CqlTimeuuid. +value::CqlTimeuuid is a wrapper for uuid::Uuid with custom ordering logic +which follows Scylla/Cassandra semantics.

        +
        use scylla::IntoTypedRows;
        +use scylla::frame::value::CqlTimeuuid;
        +
        +// Insert some timeuuid into the table
        +let to_insert: CqlTimeuuid = CqlTimeuuid::from_str("8e14e760-7fa8-11eb-bc66-000000000001")?;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read timeuuid from the table
        +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
        +    for row in rows.into_typed::<(CqlTimeuuid,)>() {
        +        let (timeuuid_value,): (CqlTimeuuid,) = row?;
        +    }
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/tuple.html b/stable/data-types/tuple.html new file mode 100644 index 0000000000..0989693e3e --- /dev/null +++ b/stable/data-types/tuple.html @@ -0,0 +1,629 @@ + + + + + + + + + + + + + Tuple | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Tuple

        +

        Tuple is represented as rust tuples of max 16 elements.

        +
        use scylla::IntoTypedRows;
        +
        +// Insert a tuple of int and string into the table
        +let to_insert: (i32, String) = (1, "abc".to_string());
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a tuple of int and string from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<((i32, String),)>()?;
        +while let Some((tuple_value,)) = iter.next().transpose()? {
        +    let int_value: i32 = tuple_value.0;
        +    let string_value: String = tuple_value.1;
        +    println!("({}, {})", int_value, string_value);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/udt.html b/stable/data-types/udt.html new file mode 100644 index 0000000000..6a29e8a34e --- /dev/null +++ b/stable/data-types/udt.html @@ -0,0 +1,679 @@ + + + + + + + + + + + + + User defined types | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        User defined types

        +

        Scylla allows users to define their own data types with named fields (See the official documentation)
        +To use user defined types in the driver, you can create a corresponding struct in Rust, and use it to read and write UDT values.

        +

        For example let’s say my_type was created using this query:

        +
        CREATE TYPE ks.my_type (int_val int, text_val text)
        +
        +
        +

        To use this type in the driver, create a matching struct and derive:

        +
          +
        • SerializeCql: in order to be able to use this struct in query parameters.
          +This macro requires fields of UDT and struct to have matching names, but the order +of the fields is not required to be the same.
          +Note: you can use different name using rename attribute - see SerializeCql macro documentation.

        • +
        • FromUserType: in order to be able to use this struct in query results.
          +This macro requires fields of UDT and struct to be in the same ORDER.
          +This mismatch between SerializeCql and FromUserType requirements is a temporary situation - in the future FromUserType (or the macro that replaces it) will also require matching names.

        • +
        +
        use scylla::macros::{FromUserType, SerializeCql};
        +
        +// Define a custom struct that matches the User Defined Type created earlier.
        +// Fields must be in the same order as they are in the database and also
        +// have the same names.
        +// Wrapping a field in Option will gracefully handle null field values.
        +#[derive(Debug, FromUserType, SerializeCql)]
        +struct MyType {
        +    int_val: i32,
        +    text_val: Option<String>,
        +}
        +
        +
        +
        +

        Important
        +For deserialization, fields in the Rust struct must be defined in the same order as they are in the database. +When receiving values, the driver will (de)serialize fields one after another, without looking at field names.

        +
        +
        +

        Important
        +For serialization, by default fields in the Rust struct must be defined with the same names as they are in the database. +The driver will serialize the fields in the order defined by the UDT, matching Rust fields by name. +You can change this behaviour using macro attributes, see SerializeCql macro documentation for more information.

        +
        +

        Now it can be sent and received just like any other CQL value:

        +
        use scylla::IntoTypedRows;
        +use scylla::macros::{FromUserType, SerializeCql};
        +use scylla::cql_to_rust::FromCqlVal;
        +
        +#[derive(Debug, FromUserType, SerializeCql)]
        +struct MyType {
        +    int_val: i32,
        +    text_val: Option<String>,
        +}
        +
        +// Insert my_type into the table
        +let to_insert = MyType {
        +    int_val: 17,
        +    text_val: Some("Some string".to_string()),
        +};
        +
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read MyType from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(MyType,)>()?;
        +while let Some((my_type_value,)) = iter.next().transpose()? {
        +    println!("{:?}", my_type_value);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/uuid.html b/stable/data-types/uuid.html new file mode 100644 index 0000000000..553f63038f --- /dev/null +++ b/stable/data-types/uuid.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + + Uuid | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Uuid

        +

        Uuid is represented as uuid::Uuid.

        +
        use scylla::IntoTypedRows;
        +use uuid::Uuid;
        +
        +// Insert some uuid into the table
        +let to_insert: Uuid = Uuid::parse_str("8e14e760-7fa8-11eb-bc66-000000000001")?;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read uuid from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(Uuid,)>()?;
        +while let Some((uuid_value,)) = iter.next().transpose()? {
        +    println!("{:?}", uuid_value);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/data-types/varint.html b/stable/data-types/varint.html new file mode 100644 index 0000000000..caeb90c1d4 --- /dev/null +++ b/stable/data-types/varint.html @@ -0,0 +1,654 @@ + + + + + + + + + + + + + Varint | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Varint

        +

        Varint is represented as value::CqlVarint or num_bigint::BigInt.

        +
        +

        num_bigint::BigInt

        +

        To make use of num_bigint::BigInt type, user should enable one of the available feature flags (num-bigint-03 or num-bigint-04). They enable support for num_bigint::BigInt v0.3 and v0.4 accordingly.

        +
        +
        +

        value::CqlVarint

        +

        Without any feature flags, the user can interact with Varint type by making use of value::CqlVarint which +is a very simple wrapper representing the value as signed binary number in big-endian order.

        +
        +
        +

        Example

        +
        use scylla::IntoTypedRows;
        +use num_bigint::BigInt;
        +use std::str::FromStr;
        +
        +// Insert a varint into the table
        +let to_insert: BigInt = BigInt::from_str("12345")?;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +// Read a varint from the table
        +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
        +let mut iter = result.rows_typed::<(BigInt,)>()?;
        +while let Some((varint_value,)) = iter.next().transpose()? {
        +    println!("{:?}", varint_value);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/execution-profiles/create-and-use.html b/stable/execution-profiles/create-and-use.html new file mode 100644 index 0000000000..2766df2fee --- /dev/null +++ b/stable/execution-profiles/create-and-use.html @@ -0,0 +1,685 @@ + + + + + + + + + + + + + Creating a profile and setting it | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Creating a profile and setting it

        +
        +

        Example

        +

        To create an ExecutionProfile and attach it as default for Session:

        +
        use scylla::{Session, SessionBuilder};
        +use scylla::statement::Consistency;
        +use scylla::transport::ExecutionProfile;
        +
        +let profile = ExecutionProfile::builder()
        +    .consistency(Consistency::LocalOne)
        +    .request_timeout(None) // no request timeout
        +    .build();
        +
        +let handle = profile.into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .default_execution_profile_handle(handle)
        +    .build()
        +    .await?;
        +
        +
        +
        +
        +

        Example

        +

        To create an ExecutionProfile and attach it to a Query:

        +
        use scylla::query::Query;
        +use scylla::statement::Consistency;
        +use scylla::transport::ExecutionProfile;
        +use std::time::Duration;
        +
        +let profile = ExecutionProfile::builder()
        +    .consistency(Consistency::All)
        +    .request_timeout(Some(Duration::from_secs(30)))
        +    .build();
        +
        +let handle = profile.into_handle();
        +
        +let mut query1 = Query::from("SELECT * FROM ks.table");
        +query1.set_execution_profile_handle(Some(handle.clone()));
        +
        +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?");
        +query2.set_execution_profile_handle(Some(handle));
        +
        +
        +
        +
        +

        Example

        +

        To create an ExecutionProfile based on another profile:

        +
        use scylla::statement::Consistency;
        +use scylla::transport::ExecutionProfile;
        +use std::time::Duration;
        +
        +let base_profile = ExecutionProfile::builder()
        +    .request_timeout(Some(Duration::from_secs(30)))
        +    .build();
        +
        +let profile = base_profile.to_builder()
        +    .consistency(Consistency::All)
        +    .build();
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/execution-profiles/execution-profiles.html b/stable/execution-profiles/execution-profiles.html new file mode 100644 index 0000000000..9d80c0104e --- /dev/null +++ b/stable/execution-profiles/execution-profiles.html @@ -0,0 +1,619 @@ + + + + + + + + + + + + + Execution profiles | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Execution profiles

        +

        Execution profiles are a way to group various query execution configuration options together. Profiles can be created to represent different workloads, which can be run conveniently on a single session.

        +

        The settings that an execution profile encapsulates are as follows:

        +
          +
        • consistency

        • +
        • serial consistency

        • +
        • request timeout

        • +
        • load balancing policy

        • +
        • retry policy

        • +
        • speculative execution policy

        • +
        +

        There are two classes of objects related to execution profiles: ExecutionProfile and ExecutionProfileHandle. The former is simply an immutable set of the settings. The latter is a handle that at particular moment points to some ExecutionProfile (but during its lifetime, it can change the profile it points at). Handles are assigned to Sessions and Statements.
        +
        +At any moment, handles can be remapped to point to another ExecutionProfile. This allows convenient switching between workloads for all Sessions and/or Statements that, for instance, share common characteristics.

        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/execution-profiles/maximal-example.html b/stable/execution-profiles/maximal-example.html new file mode 100644 index 0000000000..9893c993d5 --- /dev/null +++ b/stable/execution-profiles/maximal-example.html @@ -0,0 +1,655 @@ + + + + + + + + + + + + + All options supported by a profile | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        All options supported by a profile

        +
        +

        Example

        +

        ExecutionProfile supports all the following options:

        +
        use scylla::query::Query;
        +use scylla::speculative_execution::SimpleSpeculativeExecutionPolicy;
        +use scylla::statement::{Consistency, SerialConsistency};
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::load_balancing::DefaultPolicy;
        +use scylla::transport::retry_policy::FallthroughRetryPolicy;
        +use std::{sync::Arc, time::Duration};
        +
        +let profile = ExecutionProfile::builder()
        +    .consistency(Consistency::All)
        +    .serial_consistency(Some(SerialConsistency::Serial))
        +    .request_timeout(Some(Duration::from_secs(30)))
        +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
        +    .load_balancing_policy(Arc::new(DefaultPolicy::default()))
        +    .speculative_execution_policy(
        +        Some(
        +            Arc::new(
        +                SimpleSpeculativeExecutionPolicy {
        +                    max_retry_count: 3,
        +                    retry_interval: Duration::from_millis(100),
        +                }
        +            )
        +        )
        +    )
        +    .build();
        +
        +let mut query = Query::from("SELECT * FROM ks.table");
        +query.set_execution_profile_handle(Some(profile.into_handle()));
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/execution-profiles/priority.html b/stable/execution-profiles/priority.html new file mode 100644 index 0000000000..b45375927e --- /dev/null +++ b/stable/execution-profiles/priority.html @@ -0,0 +1,667 @@ + + + + + + + + + + + + + Priorities of execution settings | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Priorities of execution settings

        +

        You always have a default execution profile set for the Session, either the default one or overridden upon Session creation. Moreover, you can set a profile for specific statements, in which case the statement’s profile has higher priority. Some options are also available for specific statements to be set directly on them, such as request timeout and consistency. In such case, the directly set options are preferred over those specified in execution profiles.

        +
        +

        Recap
        +Priorities are as follows:
        +Session’s default profile < Statement’s profile < options set directly on a Statement

        +
        +
        +

        Example

        +

        Priorities of execution profiles and directly set options:

        +
        use scylla::{Session, SessionBuilder};
        +use scylla::query::Query;
        +use scylla::statement::Consistency;
        +use scylla::transport::ExecutionProfile;
        +
        +let session_profile = ExecutionProfile::builder()
        +    .consistency(Consistency::One)
        +    .build();
        +
        +let query_profile = ExecutionProfile::builder()
        +    .consistency(Consistency::Two)
        +    .build();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .default_execution_profile_handle(session_profile.into_handle())
        +    .build()
        +    .await?;
        +
        +let mut query = Query::from("SELECT * FROM ks.table");
        +
        +// Query is not assigned any specific profile, so session's profile is applied.
        +// Therefore, the query will be executed with Consistency::One.
        +session.query(query.clone(), ()).await?;
        +
        +query.set_execution_profile_handle(Some(query_profile.into_handle()));
        +// Query's profile is applied.
        +// Therefore, the query will be executed with Consistency::Two.
        +session.query(query.clone(), ()).await?;
        +
        +query.set_consistency(Consistency::Three);
        +// An option is set directly on the query.
        +// Therefore, the query will be executed with Consistency::Three.
        +session.query(query, ()).await?;
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/execution-profiles/remap.html b/stable/execution-profiles/remap.html new file mode 100644 index 0000000000..cd930279bd --- /dev/null +++ b/stable/execution-profiles/remap.html @@ -0,0 +1,690 @@ + + + + + + + + + + + + + Remapping execution profile handles | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Remapping execution profile handles

        +

        ExecutionProfileHandles can be remapped to another ExecutionProfile, and the change affects all sessions and statements that have been assigned that handle. This enables quick workload switches.

        +

        Example mapping:

        +
          +
        • session1 -> handle1 -> profile1

        • +
        • statement1 -> handle1 -> profile1

        • +
        • statement2 -> handle2 -> profile2

        • +
        +

        We can now remap handle2 to profile1, so that the mapping for statement2 becomes as follows:

        +
          +
        • statement2 -> handle2 -> profile1

        • +
        +

        We can also change statement1’s handle to handle2, and remap handle1 to profile2, yielding:

        +
          +
        • session1 -> handle1 -> profile2

        • +
        • statement1 -> handle2 -> profile1

        • +
        • statement2 -> handle2 -> profile1

        • +
        +

        As you can see, profiles are a powerful and convenient way to define and modify your workloads.

        +
        +

        Example

        +

        Below, the remaps described above are followed in code.

        +
        use scylla::{Session, SessionBuilder};
        +use scylla::query::Query;
        +use scylla::statement::Consistency;
        +use scylla::transport::ExecutionProfile;
        +
        +let profile1 = ExecutionProfile::builder()
        +    .consistency(Consistency::One)
        +    .build();
        +
        +let profile2 = ExecutionProfile::builder()
        +    .consistency(Consistency::Two)
        +    .build();
        +
        +let mut handle1 = profile1.clone().into_handle();
        +let mut handle2 = profile2.clone().into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .default_execution_profile_handle(handle1.clone())
        +    .build()
        +    .await?;
        +
        +let mut query1 = Query::from("SELECT * FROM ks.table");
        +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?");
        +
        +query1.set_execution_profile_handle(Some(handle1.clone()));
        +query2.set_execution_profile_handle(Some(handle2.clone()));
        +
        +// session1 -> handle1 -> profile1
        +// query1 -> handle1 -> profile1
        +// query2 -> handle2 -> profile2
        +
        +// We can now remap handle2 to profile1:
        +handle2.map_to_another_profile(profile1);
        +// ...so that the mapping for query2 becomes as follows:
        +// query2 -> handle2 -> profile1
        +
        +// We can also change query1's handle to handle2:
        +query1.set_execution_profile_handle(Some(handle2.clone()));
        +// ...and remap handle1 to profile2:
        +handle1.map_to_another_profile(profile2);
        +// ...yielding:
        +// session1 -> handle1 -> profile2
        +// query1 -> handle2 -> profile1
        +// query2 -> handle2 -> profile1
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/genindex.html b/stable/genindex.html new file mode 100644 index 0000000000..2eaf296be8 --- /dev/null +++ b/stable/genindex.html @@ -0,0 +1,585 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + + + +
        + + + + + +
        + + +
        + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/index.html b/stable/index.html new file mode 100644 index 0000000000..59984cf608 --- /dev/null +++ b/stable/index.html @@ -0,0 +1,636 @@ + + + + + + + + + + + + + Scylla Rust Driver | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Scylla Rust Driver

        +

        This book contains documentation for scylla-rust-driver - a driver +for the Scylla database written in Rust. +Although optimized for Scylla, the driver is also compatible with Apache Cassandra®.

        +
        +

        Other documentation

        + +
        +
        +

        Contents

        + +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/load-balancing/default-policy.html b/stable/load-balancing/default-policy.html new file mode 100644 index 0000000000..b759b74e33 --- /dev/null +++ b/stable/load-balancing/default-policy.html @@ -0,0 +1,792 @@ + + + + + + + + + + + + + DefaultPolicy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        DefaultPolicy

        +

        DefaultPolicy is the default load balancing policy in Scylla Rust Driver. It +can be configured to be datacenter-aware and token-aware. Datacenter failover +for queries with non-local consistency mode is also supported.

        +
        +

        Creating a DefaultPolicy

        +

        DefaultPolicy can be created only using DefaultPolicyBuilder. The +builder() method of DefaultPolicy returns a new instance of +DefaultPolicyBuilder with the following default values:

        +
          +
        • preferences: no particular datacenter/rack preference

        • +
        • is_token_aware: true

        • +
        • permit_dc_failover: false

        • +
        • latency_awareness: None

        • +
        +

        You can use the builder methods to configure the desired settings and create a +DefaultPolicy instance:

        +
        use scylla::load_balancing::DefaultPolicy;
        +
        +let default_policy = DefaultPolicy::builder()
        +        .prefer_datacenter_and_rack("dc1".to_string(), "rack1".to_string())
        +        .token_aware(true)
        +        .permit_dc_failover(true)
        +        .build();
        +
        +
        +
        +

        Semantics of DefaultPolicy

        +
        +

        Preferences

        +

        The preferences field in DefaultPolicy allows the load balancing +policy to prioritize nodes based on their location. It has three modes:

        +
          +
        • no preference

        • +
        • preferred datacenter

        • +
        • preferred datacenter and rack

        • +
        +

        When a datacenter "my_dc" is preferred, the policy will treat nodes in "my_dc" +as “local” nodes, and nodes in other datacenters as “remote” nodes. This affects +the order in which nodes are returned by the policy when selecting nodes for +read or write operations. If no datacenter is preferred, the policy will treat +all nodes as local nodes.

        +

        preferences allow the load balancing policy to prioritize nodes based on their +availability zones (racks) in the preferred datacenter, too. When a datacenter +and a rack are preferred, the policy will first return replicas in the local rack +in the preferred datacenter, and then the other replicas in the datacenter +(followed by remote replicas). After replicas, the other node will be ordered +similarly, too (local rack nodes, local datacenter nodes, remote nodes).

        +

        When datacenter failover is disabled (permit_dc_failover is set to +false), the default policy will only include local nodes in load balancing +plans. Remote nodes will be excluded, even if they are alive and available to +serve requests.

        +
        +
        +

        Datacenter Failover

        +

        In the event of a datacenter outage or network failure, the nodes in that +datacenter may become unavailable, and clients may no longer be able to access +the data stored on those nodes. To address this, the DefaultPolicy supports +datacenter failover, which allows to route requests to nodes in other datacenters +if the local nodes are unavailable.

        +

        Datacenter failover can be enabled in DefaultPolicy by permit_dc_failover +setting in the builder. When this flag is set, the policy will prefer to return +alive remote replicas if datacenter failover is permitted and possible due to +consistency constraints.

        +
        +
        +

        Token awareness

        +

        Token awareness refers to a mechanism by which the driver is aware of the token +range assigned to each node in the cluster. Tokens are assigned to nodes to +partition the data and distribute it across the cluster.

        +

        When a user wants to read or write data, the driver can use token awareness to +route the request to the correct node based on the token range of the data +being accessed. This can help to minimize network traffic and improve +performance by ensuring that the data is accessed locally as much as possible.

        +

        In the case of DefaultPolicy, token awareness is enabled by default, meaning +that the policy will prefer to return alive local replicas if the token is +available. This means that if the client is requesting data that falls within +the token range of a particular node, the policy will try to route the request +to that node first, assuming it is alive and responsive.

        +

        Token awareness can significantly improve the performance and scalability of +applications built on Scylla. By using token awareness, users can ensure that +data is accessed locally as much as possible, reducing network overhead and +improving throughput.

        +

        Please note that for token awareness to be applied, a statement must be +prepared before being executed.

        +
        +
        +
        +

        Latency awareness

        +

        Latency awareness is a mechanism that penalises nodes whose measured recent +average latency classifies it as falling behind the others.

        +

        Every update_rate the global minimum average latency is computed, +and all nodes whose average latency is worse than exclusion_threshold +times the global minimum average latency become penalised for +retry_period. Penalisation involves putting those nodes at the very end +of the query plan. As it is often not truly beneficial to prefer +faster non-replica than replicas lagging behind the non-replicas, +this mechanism may as well worsen latencies and/or throughput.

        +
        +

        Warning

        +

        Using latency awareness is NOT recommended, unless prior +benchmarks prove its beneficial impact on the specific workload’s +performance. Use with caution.

        +
        +
        +
        +

        Creating a latency aware DefaultPolicy

        +
        use scylla::load_balancing::{
        +    LatencyAwarenessBuilder, DefaultPolicy
        +};
        +use std::time::Duration;
        +
        +let latency_awareness_builder = LatencyAwarenessBuilder::new()
        +    .exclusion_threshold(3.)
        +    .update_rate(Duration::from_secs(3))
        +    .retry_period(Duration::from_secs(30))
        +    .minimum_measurements(200);
        +
        +let policy = DefaultPolicy::builder()
        +        // Here further customisation is, of course, possible.
        +        // e.g.: .prefer_datacenter(...)
        +        .latency_awareness(latency_awareness_builder)
        +        .build();
        +
        +
        +
        use scylla::load_balancing::DefaultPolicy;
        +
        +let default_policy = DefaultPolicy::builder()
        +        .prefer_datacenter("dc1".to_string())
        +        .token_aware(true)
        +        .permit_dc_failover(true)
        +        .build();
        +
        +
        +
        +
        +

        Node order in produced plans

        +

        The DefaultPolicy prefers to return nodes in the following order:

        +
          +
        1. Alive local replicas (if token is available & token awareness is enabled)

        2. +
        3. Alive remote replicas (if datacenter failover is permitted & possible due to consistency constraints)

        4. +
        5. Alive local nodes

        6. +
        7. Alive remote nodes (if datacenter failover is permitted & possible due to consistency constraints)

        8. +
        9. Enabled down nodes +And only if latency awareness is enabled:

        10. +
        11. Penalised: alive local replicas, alive remote replicas, … (in order as above).

        12. +
        +

        If no preferred datacenter is specified, all nodes are treated as local ones.

        +

        Replicas in the same priority groups are shuffled[1]. Non-replicas are randomly +rotated (similarly to a round robin with a random index).

        +
        + +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/load-balancing/load-balancing.html b/stable/load-balancing/load-balancing.html new file mode 100644 index 0000000000..8085a47b2f --- /dev/null +++ b/stable/load-balancing/load-balancing.html @@ -0,0 +1,726 @@ + + + + + + + + + + + + + Load balancing | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Load balancing

        +
        +

        Introduction

        +

        The driver uses a load balancing policy to determine which node(s) and shard(s) +to contact when executing a query. Load balancing policies implement the +LoadBalancingPolicy trait, which contains methods to generate a load +balancing plan based on the query information and the state of the cluster.

        +

        Load balancing policies do not influence to which nodes connections are +being opened. For a node connection blacklist configuration refer to +scylla::transport::host_filter::HostFilter, which can be set session-wide +using SessionBuilder::host_filter method.

        +

        In this chapter, “target” will refer to a pair <node, optional shard>.

        +
        +
        +

        Plan

        +

        When a query is prepared to be sent to the database, the load balancing policy +constructs a load balancing plan. This plan is essentially a list of targets to +which the driver will try to send the query. The first elements of the plan are +the targets which are the best to contact (e.g. they might be replicas for the +requested data or have the best latency).

        +
        +
        +

        Policy

        +

        The Scylla/Cassandra driver provides a default load balancing policy (see +Default Policy for details), but you can +also implement your own custom policies that better suit your specific use +case. To use a custom policy, you simply need to implement the +LoadBalancingPolicy trait and pass an instance of your custom policy to the +used execution profile.

        +

        Our recommendation is to use Default Policy with token- +awareness enabled and latency-awareness disabled.

        +
        +
        +

        Configuration

        +

        Load balancing policies can be configured via execution profiles. In the code +sample provided, a new execution profile is created using +ExecutionProfile::builder(), and the load balancing policy is set to the +DefaultPolicy using .load_balancing_policy(policy).

        +

        The newly created execution profile is then converted to a handle using +.into_handle(), and passed as the default execution profile to the +SessionBuilder using .default_execution_profile_handle(handle).

        +
        use scylla::SessionBuilder;
        +use scylla::load_balancing::DefaultPolicy;
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::session::Session;
        +use std::sync::Arc;
        +
        +let policy = Arc::new(DefaultPolicy::default());
        +
        +let profile = ExecutionProfile::builder()
        +    .load_balancing_policy(policy)
        +    .build();
        +let handle = profile.into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node(&uri)
        +    .default_execution_profile_handle(handle)
        +    .build()
        +    .await?;
        +
        +
        +

        In addition to being able to configure load balancing policies through +execution profiles at the session level, the driver also allow for setting +execution profile handles on a per-query basis. This means that for each query, +a specific execution profile can be selected with a customized load balancing +settings.

        +
        +
        +

        LoadBalancingPolicy trait

        +
        +

        pick and fallback:

        +

        Most queries are sent successfully on the first try. In such cases, only the +first element of the load balancing plan is needed, so it’s usually unnecessary +to compute entire load balancing plan. To optimize this common case, the +LoadBalancingPolicy trait provides two methods: pick and fallback.

        +

        pick returns the first target to contact for a given query, which is usually +the best based on a particular load balancing policy.

        +

        fallback, returns an iterator that provides the rest of the targets in the +load balancing plan. fallback is called when using the initial picked +target fails (or when executing speculatively) or when pick returned None.

        +

        It’s possible for the fallback method to include the same target that was +returned by the pick method. In such cases, the query execution layer filters +out the picked target from the iterator returned by fallback.

        +
        +
        +

        on_query_success and on_query_failure:

        +

        The on_query_success and on_query_failure methods are useful for load +balancing policies because they provide feedback on the performance and health +of the nodes in the cluster.

        +

        When a query is successfully executed, the on_query_success method is called +and can be used by the load balancing policy to update its internal state. For +example, a policy might use the latency of the successful query to update its +latency statistics for each node in the cluster. This information can be used +to make decisions about which nodes to contact in the future.

        +

        On the other hand, when a query fails to execute, the on_query_failure method +is called and provides information about the failure. The error message +returned by Cassandra can help determine the cause of the failure, such as a +node being down or overloaded. The load balancing policy can use this +information to update its internal state and avoid contacting the same node +again until it’s recovered.

        +
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/logging/logging.html b/stable/logging/logging.html new file mode 100644 index 0000000000..4ac54a3640 --- /dev/null +++ b/stable/logging/logging.html @@ -0,0 +1,641 @@ + + + + + + + + + + + + + Logging | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Logging

        +

        The driver uses the tracing crate for all logs.
        +To view the logs you have to create a tracing subscriber to which all logs will be written.

        +

        To just print the logs you can use the default subscriber:

        +
        use tracing::info;
        +
        +#[tokio::main]
        +async fn main() -> Result<(), Box<dyn Error>> {
        +    // Install global collector configured based on RUST_LOG env var
        +    // This collector will receive logs from the driver
        +    tracing_subscriber::fmt::init();
        +
        +    let uri = std::env::var("SCYLLA_URI")
        +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
        +
        +    info!("Connecting to {}", uri);
        +
        +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
        +    session
        +        .query(
        +            "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \
        +            {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}",
        +            &[],
        +        )
        +        .await?;
        +
        +    // This query should generate a warning message
        +    session.query("USE ks", &[]).await?;
        +
        +    Ok(())
        +}
        +
        +
        +

        To start this example execute:

        +
        RUST_LOG=info cargo run
        +
        +
        +

        The full example is available in the examples folder

        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/metrics/metrics.html b/stable/metrics/metrics.html new file mode 100644 index 0000000000..ccca65190b --- /dev/null +++ b/stable/metrics/metrics.html @@ -0,0 +1,645 @@ + + + + + + + + + + + + + Driver metrics | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Driver metrics

        +

        During operation the driver collects various metrics.

        +

        They can be accessed at any moment using Session::get_metrics()

        +
        +

        Collected metrics:

        +
          +
        • Query latencies

        • +
        • Total number of nonpaged queries

        • +
        • Number of errors during nonpaged queries

        • +
        • Total number of paged queries

        • +
        • Number of errors during paged queries

        • +
        • Number of retries

        • +
        +
        +
        +

        Example

        +
        let metrics = session.get_metrics();
        +
        +println!("Queries requested: {}", metrics.get_queries_num());
        +println!("Iter queries requested: {}", metrics.get_queries_iter_num());
        +println!("Errors occurred: {}", metrics.get_errors_num());
        +println!("Iter errors occurred: {}", metrics.get_errors_iter_num());
        +println!("Average latency: {}", metrics.get_latency_avg_ms().unwrap());
        +println!(
        +    "99.9 latency percentile: {}",
        +    metrics.get_latency_percentile_ms(99.9).unwrap()
        +);
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/migration-guides/0.11-serialization.html b/stable/migration-guides/0.11-serialization.html new file mode 100644 index 0000000000..da93b9e3db --- /dev/null +++ b/stable/migration-guides/0.11-serialization.html @@ -0,0 +1,723 @@ + + + + + + + + + + + + + Adjusting code to changes in serialization API introduced in 0.11 | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Adjusting code to changes in serialization API introduced in 0.11

        +
        +

        Background

        +

        When executing a statement through the CQL protocol, values for the bind markers are sent in a serialized, untyped form. In order to implement a safer and more robust interface, drivers can use the information returned after preparing a statement to check the type of data provided by the user against the actual types of the bind markers.

        +

        Before 0.11, the driver couldn’t do this kind of type checking. For example, in the case of non-batch queries, the only information about the user data it has is that it implements ValueList - defined as follows:

        +
        pub trait ValueList {
        +    fn serialized(&self) -> SerializedResult<'_>;
        +    fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError>;
        +}
        +
        +
        +

        The driver would naively serialize the data and hope that the user took care to send correct types of values. Failing to do so would, in the best case, fail on the DB-side validation; in the worst case, the data in its raw form may be reinterpreted as another type in an unintended manner.

        +

        Another problem is that the information from the prepared statement response is required to robustly serialize user defined types, as UDTs require their fields to be serialized in the same order as they are defined in the database schema. The IntoUserType macro which implements Rust struct -> UDT serialization just expects that the order of the Rust struct fields matches the schema, but ensuring this can be very cumbersome for the users.

        +

        In version 0.11, a new set of traits is introduced and the old ones are deprecated. The new traits receive more information during serialization such as names of the column/bind markers and their types, which allows to fix the issues mentioned in the previous section.

        +
        +
        +

        Old vs. new

        +

        Both the old and the new APIs are based on three core traits:

        +
          +
        • Value - called SerializeCql in the new API. A type that can serialize itself to a single CQL value. For example, i32 serializes itself into a representation that is compatible with the CQL int type.

        • +
        • ValueList - called SerializeRow in the new API. A type that can serialize itself as a list of values for a CQL statement. For example, a (i32, &str) produces a list of two values which can be used in a query with two bind markers, e.g. SELECT * FROM table WHERE pk = ? AND ck = ?. Optionally, values in the produced list may be associated with names which is useful when using it with a query with named bind markers, e.g. SELECT * FROM table WHERE pk = :pk AND ck = :ck.

        • +
        • LegacyBatchValues, previously named BatchValues - in new API replaced with new trait called (again) BatchValues. Represents a source of data for a batch request. It is essentially equivalent to a list of ValueList, one for each statement in the batch. For example, ((1, 2), (3, 4, 5)) can be used for a batch with two statements, the first one having two bind markers and the second one having three.

        • +
        +

        All methods which take one of the old traits were changed to take the new trait - notably, this includes Session::query, (Caching)Session::execute, (Caching)Session::batch.

        +

        The driver comes a set of impls of those traits which allow to represent any CQL type (for example, see Data Types page for a list of for which Value and SerializeCql is implemented). If the driver implements an old trait for some type, then it also provides implements the new trait for the same type.

        +
        +
        +

        Migration scenarios

        +
        +

        Different default behavior in SerializeRow/SerializeCql macros

        +

        By default, the SerializeRow and SerializeCql will match the fields in the Rust struct by name to bind marker names (in case of SerializeRow) or UDT field names (in case of SerializeCql). This is different from the old ValueList and IntoUserType macros which did not look at the field names at all and would expect the user to order the fields correctly. While the new behavior is much more ergonomic, you might have reasons not to use it.

        +
        +

        NOTE: The deserialization macro counterparts FromRow and FromUserType have the same limitation as the old serialization macros - they require struct fields to be properly ordered. While a similar rework is planned for the deserialization traits in a future release, for the time being it might not be worth keeping the column names in sync with the database.

        +
        +

        In order to bring the old behavior to the new macros (the only difference being type checking which cannot be disabled right now) you can configure it using attributes, as shown in the snippet below:

        +
        use scylla::SerializeCql;
        +
        +// The exact same attributes apply to the `SerializeRow` macro and their
        +// effect is completely analogous.
        +#[derive(SerializeCql)]
        +#[scylla(flavor = "enforce_order", skip_name_checks)]
        +struct Person {
        +    name: String,
        +    surname: String,
        +    age: i16,
        +}
        +
        +
        +

        Refer to the API reference page for the SerializeRow and SerializeCql macros in the scylla crate to learn more about the supported attributes and their meaning.

        +
        +
        +

        Preparing is mandatory with a non-empty list of values

        +
        +

        NOTE: The considerations in this section only concerns users of the Session API, CachingSession is not affected as it already does preparation before execute and caches the result.

        +
        +

        As explained in the Background section, the driver uses data returned from the database after preparing a statement in order to implement type checking. As the new API makes type checking mandatory, the driver must prepare the statement so that the data for the bind markers can be type checked. It is done in case of the existing methods which used to send unprepared statements: Session::query and Session::batch.

        +
        +

        NOTE: The driver will skip preparation if it detects that the list of values for the statement is empty, as there is nothing to be type checked.

        +
        +

        If you send simple statements along with non-empty lists of values, the slowdown will be as follows:

        +
          +
        • For Session::query, the driver will prepare the statement before sending it, incurring an additional round-trip.

        • +
        • For Session::batch, the driver will send a prepare request for each unique unprepared statement with a non-empty list of values. This is done serially!

        • +
        +

        In both cases, if the additional roundtrips are unacceptable, you should prepare the statements beforehand and reuse them - which aligns with our general recommendation against use of simple statements in performance sensitive scenarios.

        +
        +
        +

        Migrating from old to new traits gradually

        +

        In some cases, migration will be as easy as changing occurrences of IntoUserType to SerializeCql and ValueList to SerializeRow and adding some atributes for procedural macros. However, if you have a large enough codebase or some custom, complicated implementations of the old traits then you might not want to migrate everything at once. To support gradual migration, the old traits were not removed but rather deprecated, and we introduced some additional utilities.

        +
        +

        Converting an object implementing an old trait to a new trait

        +

        We provide a number of newtype wrappers:

        +
          +
        • ValueAdapter - implements SerializeCql if the type wrapped over implements Value,

        • +
        • ValueListAdapter - implements SerializeRow if the type wrapped over implements ValueList,

        • +
        • LegacyBatchValuesAdapter - implements BatchValues if the type wrapped over implements LegacyBatchValues.

        • +
        +

        Note that these wrappers are not zero cost and incur some overhead: in case of ValueAdapter and ValueListAdapter, the data is first written into a newly allocated buffer and then rewritten to the final buffer. In case of LegacyBatchValuesAdapter there shouldn’t be any additional allocations unless the implementation has an efficient, non-default Self::LegacyBatchValuesIterator::write_next_to_request implementation (which is not the case for the built-in impls).

        +

        Naturally, the implementations provided by the wrappers are not type safe as they directly use methods from the old traits.

        +

        Conversion in the other direction is not possible.

        +
        +
        +

        Custom implementations of old traits

        +

        It is possible to directly generate an impl of SerializeRow and SerializeCql on a type which implements, respectively, ValueList or Value, without using the wrappers from the previous section. The following macros are provided:

        +
          +
        • impl_serialize_cql_via_value - implements SerializeCql if the type wrapped over implements Value,

        • +
        • impl_serialize_row_via_value_list - implements SerializeRow if the type wrapped over implements ValueList,

        • +
        +

        The implementations are practically as those generated by the wrappers described in the previous section.

        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/migration-guides/migration-guides.html b/stable/migration-guides/migration-guides.html new file mode 100644 index 0000000000..5016549ca2 --- /dev/null +++ b/stable/migration-guides/migration-guides.html @@ -0,0 +1,609 @@ + + + + + + + + + + + + + Migration guides | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Migration guides

        + +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/objects.inv b/stable/objects.inv new file mode 100644 index 0000000000..5d605ef479 Binary files /dev/null and b/stable/objects.inv differ diff --git a/stable/queries/batch.html b/stable/queries/batch.html new file mode 100644 index 0000000000..4215f12f83 --- /dev/null +++ b/stable/queries/batch.html @@ -0,0 +1,746 @@ + + + + + + + + + + + + + Batch statement | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Batch statement

        +

        A batch statement allows to execute many data-modifying statements at once.
        +These statements can be simple or prepared.
        +Only INSERT, UPDATE and DELETE statements are allowed.

        +
        use scylla::batch::Batch;
        +use scylla::query::Query;
        +use scylla::prepared_statement::PreparedStatement;
        +
        +// Create a batch statement
        +let mut batch: Batch = Default::default();
        +
        +// Add a simple statement to the batch using its text
        +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(1, 2)");
        +
        +// Add a simple statement created manually to the batch
        +let simple: Query = Query::new("INSERT INTO ks.tab (a, b) VALUES(3, 4)");
        +batch.append_statement(simple);
        +
        +// Add a prepared statement to the batch
        +let prepared: PreparedStatement = session
        +    .prepare("INSERT INTO ks.tab (a, b) VALUES(?, 6)")
        +    .await?;
        +batch.append_statement(prepared);
        +
        +// Specify bound values to use with each statement
        +let batch_values = ((),
        +                    (),
        +                    (5_i32,));
        +
        +// Run the batch
        +session.batch(&batch, batch_values).await?;
        +
        +
        +
        +

        Warning
        +Using simple statements with bind markers in batches is strongly discouraged. +For each simple statement with a non-empty list of values in the batch, +the driver will send a prepare request, and it will be done sequentially. +Results of preparation are not cached between Session::batch calls. +Consider preparing the statements before putting them into the batch.

        +
        +
        +

        Preparing a batch

        +

        Instead of preparing each statement individually, it’s possible to prepare a whole batch at once:

        +
        use scylla::batch::Batch;
        +
        +// Create a batch statement with unprepared statements
        +let mut batch: Batch = Default::default();
        +batch.append_statement("INSERT INTO ks.simple_unprepared1 VALUES(?, ?)");
        +batch.append_statement("INSERT INTO ks.simple_unprepared2 VALUES(?, ?)");
        +
        +// Prepare all statements in the batch at once
        +let prepared_batch: Batch = session.prepare_batch(&batch).await?;
        +
        +// Specify bound values to use with each statement
        +let batch_values = ((1_i32, 2_i32),
        +                    (3_i32, 4_i32));
        +
        +// Run the prepared batch
        +session.batch(&prepared_batch, batch_values).await?;
        +
        +
        +
        +
        +

        Batch options

        +

        You can set various options by operating on the Batch object.
        +For example to change consistency:

        +
        use scylla::batch::Batch;
        +use scylla::statement::Consistency;
        +
        +// Create a batch
        +let mut batch: Batch = Default::default();
        +batch.append_statement("INSERT INTO ks.tab(a) VALUES(16)");
        +
        +// Set batch consistency to One
        +batch.set_consistency(Consistency::One);
        +
        +// Run the batch
        +session.batch(&batch, ((), )).await?;
        +
        +
        +

        See Batch API documentation +for more options

        +
        +
        +

        Batch values

        +

        Batch takes a tuple of values specified just like in simple or prepared queries.

        +

        Length of batch values must be equal to the number of statements in a batch.
        +Each statement must have its values specified, even if they are empty.

        +

        Values passed to Session::batch must implement the trait BatchValues.
        +By default this includes tuples () and slices &[] of tuples and slices which implement ValueList.

        +

        Example:

        +
        use scylla::batch::Batch;
        +
        +let mut batch: Batch = Default::default();
        +
        +// A statement with two bound values
        +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(?, ?)");
        +
        +// A statement with one bound value
        +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(3, ?)");
        +
        +// A statement with no bound values
        +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(5, 6)");
        +
        +// Batch values is a tuple of 3 tuples containing values for each statement
        +let batch_values = ((1_i32, 2_i32), // Tuple with two values for the first statement
        +                    (4_i32,),       // Tuple with one value for the second statement
        +                    ());            // Empty tuple/unit for the third statement
        +
        +// Run the batch
        +// Note that the driver will prepare the first two statements, due to them
        +// not being prepared and having a non-empty list of values.
        +session.batch(&batch, batch_values).await?;
        +
        +
        +

        For more information about sending values in a statement see Query values

        +
        +
        +

        Performance

        +

        Batch statements do not use token/shard aware load balancing, batches are sent to a random node.

        +

        Use prepared queries for best performance

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/lwt.html b/stable/queries/lwt.html new file mode 100644 index 0000000000..f66105ab5f --- /dev/null +++ b/stable/queries/lwt.html @@ -0,0 +1,642 @@ + + + + + + + + + + + + + Lightweight transaction (LWT) query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Lightweight transaction (LWT) query

        +

        A lightweight transaction query can be expressed just like any other query, via Session, with the notable difference of having an additional consistency level parameter - the serial_consistency_level.

        +
        +

        Format of the query

        +

        A lightweight transaction query is not a separate type - it can be expressed just like any other queries: via SimpleQuery, PreparedStatement, batches, and so on. The difference lays in the query string itself - when it contains a condition (e.g. IF NOT EXISTS), it becomes a lightweight transaction. It’s important to remember that CQL specification requires a separate, additional consistency level to be defined for LWT queries - serial_consistency_level. The serial consistency level can only be set to two values: SerialConsistency::Serial or SerialConsistency::LocalSerial. The “local” variant makes the transaction consistent only within the same datacenter. For convenience, Scylla Rust Driver sets the default consistency level to LocalSerial, as it’s more commonly used. For cross-datacenter consistency, please remember to always override the default with SerialConsistency::Serial.

        +
        use scylla::query::Query;
        +use scylla::statement::{Consistency, SerialConsistency};
        +
        +// Create a Query manually to change the Consistency to ONE
        +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?) IF NOT EXISTS".to_string());
        +my_query.set_consistency(Consistency::One);
        +// Use cross-datacenter serial consistency
        +my_query.set_serial_consistency(Some(SerialConsistency::Serial));
        +
        +// Insert a value into the table
        +let to_insert: i32 = 12345;
        +session.query(my_query, (to_insert,)).await?;
        +
        +
        +

        The rest of the API remains identical for LWT and non-LWT queries.

        +

        See Query API documentation for more options

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/paged.html b/stable/queries/paged.html new file mode 100644 index 0000000000..2831d74e79 --- /dev/null +++ b/stable/queries/paged.html @@ -0,0 +1,740 @@ + + + + + + + + + + + + + Paged query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Paged query

        +

        Sometimes query results might not fit in a single page. Paged queries +allow to receive the whole result page by page.

        +

        Session::query_iter and Session::execute_iter take a simple query or a prepared query +and return an async iterator over result Rows.

        +
        +

        Warning
        +In case of unprepared variant (Session::query_iter) if the values are not empty +driver will first fully prepare a query (which means issuing additional request to each +node in a cluster). This will have a performance penalty - how big it is depends on +the size of your cluster (more nodes - more requests) and the size of returned +result (more returned pages - more amortized penalty). In any case, it is preferable to +use Session::execute_iter.

        +
        +
        +

        Examples

        +

        Use query_iter to perform a simple query with paging:

        +
        use scylla::IntoTypedRows;
        +use futures::stream::StreamExt;
        +
        +let mut rows_stream = session
        +    .query_iter("SELECT a, b FROM ks.t", &[])
        +    .await?
        +    .into_typed::<(i32, i32)>();
        +
        +while let Some(next_row_res) = rows_stream.next().await {
        +    let (a, b): (i32, i32) = next_row_res?;
        +    println!("a, b: {}, {}", a, b);
        +}
        +
        +
        +

        Use execute_iter to perform a prepared query with paging:

        +
        use scylla::IntoTypedRows;
        +use scylla::prepared_statement::PreparedStatement;
        +use futures::stream::StreamExt;
        +
        +let prepared: PreparedStatement = session
        +    .prepare("SELECT a, b FROM ks.t")
        +    .await?;
        +
        +let mut rows_stream = session
        +    .execute_iter(prepared, &[])
        +    .await?
        +    .into_typed::<(i32, i32)>();
        +
        +while let Some(next_row_res) = rows_stream.next().await {
        +    let (a, b): (i32, i32) = next_row_res?;
        +    println!("a, b: {}, {}", a, b);
        +}
        +
        +
        +

        Query values can be passed to query_iter and execute_iter just like in a simple query

        +
        +
        +

        Configuring page size

        +

        It’s possible to configure the size of a single page.

        +

        On a Query:

        +
        use scylla::query::Query;
        +
        +let mut query: Query = Query::new("SELECT a, b FROM ks.t");
        +query.set_page_size(16);
        +
        +let _ = session.query_iter(query, &[]).await?; // ...
        +
        +
        +

        On a PreparedStatement:

        +
        use scylla::prepared_statement::PreparedStatement;
        +
        +let mut prepared: PreparedStatement = session
        +    .prepare("SELECT a, b FROM ks.t")
        +    .await?;
        +
        +prepared.set_page_size(16);
        +
        +let _ = session.execute_iter(prepared, &[]).await?; // ...
        +
        +
        +
        +
        +

        Passing the paging state manually

        +

        It’s possible to fetch a single page from the table, extract the paging state +from the result and manually pass it to the next query. That way, the next +query will start fetching the results from where the previous one left off.

        +

        On a Query:

        +
        use scylla::query::Query;
        +
        +let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6);
        +let res1 = session.query(paged_query.clone(), &[]).await?;
        +let res2 = session
        +    .query_paged(paged_query.clone(), &[], res1.paging_state)
        +    .await?;
        +
        +
        +
        +

        Warning
        +If the values are not empty, driver first needs to send a PREPARE request +in order to fetch information required to serialize values. This will affect +performance because 2 round trips will be required instead of 1.

        +
        +

        On a PreparedStatement:

        +
        use scylla::query::Query;
        +
        +let paged_prepared = session
        +    .prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7))
        +    .await?;
        +let res1 = session.execute(&paged_prepared, &[]).await?;
        +let res2 = session
        +    .execute_paged(&paged_prepared, &[], res1.paging_state)
        +    .await?;
        +
        +
        +
        +
        +

        Performance

        +

        Performance is the same as in non-paged variants.
        +For the best performance use prepared queries.

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/prepared.html b/stable/queries/prepared.html new file mode 100644 index 0000000000..7240fe41a2 --- /dev/null +++ b/stable/queries/prepared.html @@ -0,0 +1,728 @@ + + + + + + + + + + + + + Prepared query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Prepared query

        +

        Prepared queries provide much better performance than simple queries, +but they need to be prepared before use.

        +
        use scylla::prepared_statement::PreparedStatement;
        +
        +// Prepare the query for later execution
        +let prepared: PreparedStatement = session
        +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
        +    .await?;
        +
        +// Run the prepared query with some values, just like a simple query
        +let to_insert: i32 = 12345;
        +session.execute(&prepared, (to_insert,)).await?;
        +
        +
        +
        +

        Warning
        +For token/shard aware load balancing to work properly, all partition key values +must be sent as bound values (see performance section)

        +
        +
        +

        Warning
        +Don’t use execute to receive large amounts of data.
        +By default the query is unpaged and might cause heavy load on the cluster. +In such cases set a page size and use a paged query instead.

        +

        When page size is set, execute will return only the first page of results.

        +
        +
        +

        Session::prepare

        +

        Session::prepare takes query text and prepares the query on all nodes and shards. +If at least one succeeds returns success.

        +
        +
        +

        Session::execute

        +

        Session::execute takes a prepared query and bound values and runs the query. +Passing values and the result is the same as in simple query.

        +
        +
        +

        Query options

        +

        To specify custom options, set them on the PreparedStatement before execution. +For example to change the consistency:

        +
        use scylla::prepared_statement::PreparedStatement;
        +use scylla::statement::Consistency;
        +
        +// Prepare the query for later execution
        +let mut prepared: PreparedStatement = session
        +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
        +    .await?;
        +
        +// Set prepared query consistency to One
        +// This is the consistency with which this query will be executed
        +prepared.set_consistency(Consistency::One);
        +
        +// Run the prepared query with some values, just like a simple query
        +let to_insert: i32 = 12345;
        +session.execute(&prepared, (to_insert,)).await?;
        +
        +
        +

        See PreparedStatement API documentation +for more options.

        +
        +

        Note +Prepared statements can be created from Query structs and will inherit from +the custom options that the Query was created with. +This is especially useful when using CachingSession::execute for example.

        +
        +
        +
        +

        Performance

        +

        Prepared queries have good performance, much better than simple queries. +By default they use shard/token aware load balancing.

        +
        +

        Always pass partition key values as bound values. +Otherwise the driver can’t hash them to compute partition key +and they will be sent to the wrong node, which worsens performance.

        +
        +

        Let’s say we have a table like this:

        +
        TABLE ks.prepare_table (
        +    a int,
        +    b int,
        +    c int,
        +    PRIMARY KEY (a, b)
        +)
        +
        +
        +
        use scylla::prepared_statement::PreparedStatement;
        +
        +// WRONG - partition key value is passed in query string
        +// Load balancing will compute the wrong partition key
        +let wrong_prepared: PreparedStatement = session
        +    .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(12345, ?, 16)")
        +    .await?;
        +
        +session.execute(&wrong_prepared, (54321,)).await?;
        +
        +// GOOD - partition key values are sent as bound values
        +// Other values can be sent any way you like, it doesn't matter
        +let good_prepared: PreparedStatement = session
        +    .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(?, ?, 16)")
        +    .await?;
        +
        +session.execute(&good_prepared, (12345, 54321)).await?;
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/queries.html b/stable/queries/queries.html new file mode 100644 index 0000000000..f87170e198 --- /dev/null +++ b/stable/queries/queries.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Making queries | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Making queries

        +

        This driver supports all query types available in Scylla:

        +
          +
        • Simple queries

          +
            +
          • Easy to use

          • +
          • Poor performance

          • +
          • Primitive load balancing

          • +
          +
        • +
        • Prepared queries

          +
            +
          • Need to be prepared before use

          • +
          • Fast

          • +
          • Properly load balanced

          • +
          +
        • +
        • Batch statements

          +
            +
          • Run multiple queries at once

          • +
          • Can be prepared for better performance and load balancing

          • +
          +
        • +
        • Paged queries

          +
            +
          • Allows to read result in multiple pages when it doesn’t fit in a single response

          • +
          • Can be prepared for better performance and load balancing

          • +
          +
        • +
        +

        Additionally there is special functionality to enable USE KEYSPACE queries: +USE keyspace

        +

        Queries are fully asynchronous - you can run as many of them in parallel as you wish.

        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/result.html b/stable/queries/result.html new file mode 100644 index 0000000000..1d3c6e6ad3 --- /dev/null +++ b/stable/queries/result.html @@ -0,0 +1,748 @@ + + + + + + + + + + + + + Query result | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Query result

        +

        Session::query and Session::execute return a QueryResult with rows represented as Option<Vec<Row>>.

        +
        +

        Basic representation

        +

        Row is a basic representation of a received row. It can be used by itself, but it’s a bit awkward to use:

        +
        if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
        +    for row in rows {
        +        let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap();
        +    }
        +}
        +
        +
        +
        +
        +

        Parsing using into_typed

        +

        The driver provides a way to parse a row as a tuple of Rust types:

        +
        use scylla::IntoTypedRows;
        +
        +// Parse row as a single column containing an int value
        +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
        +    for row in rows {
        +        let (int_value,): (i32,) = row.into_typed::<(i32,)>()?;
        +    }
        +}
        +
        +// rows.into_typed() converts a Vec of Rows to an iterator of parsing results
        +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
        +    for row in rows.into_typed::<(i32,)>() {
        +        let (int_value,): (i32,) = row?;
        +    }
        +}
        +
        +// Parse row as two columns containing an int and text columns
        +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
        +    for row in rows.into_typed::<(i32, String)>() {
        +        let (int_value, text_value): (i32, String) = row?;
        +    }
        +}
        +
        +
        +
        +
        +

        Parsing using convenience methods

        +

        QueryResult provides convenience methods for parsing rows. +Here are a few of them:

        +
          +
        • rows_typed::<RowT>() - returns the rows parsed as the given type

        • +
        • maybe_first_row_typed::<RowT> - returns Option<RowT> containing first row from the result

        • +
        • first_row_typed::<RowT> - same as maybe_first_row, but fails without the first row

        • +
        • single_row_typed::<RowT> - same as first_row, but fails when there is more than one row

        • +
        • result_not_rows() - ensures that query response was not rows, helps avoid bugs

        • +
        +
        // Parse row as a single column containing an int value
        +let rows = session
        +    .query("SELECT a from ks.tab", &[])
        +    .await?
        +    .rows_typed::<(i32,)>()?; // Same as .rows()?.into_typed()
        +for row in rows {
        +    let (int_value,): (i32,) = row?;
        +}
        +
        +// maybe_first_row_typed gets the first row and parses it as the given type
        +let first_int_val: Option<(i32,)> = session
        +    .query("SELECT a from ks.tab", &[])
        +    .await?
        +    .maybe_first_row_typed::<(i32,)>()?;
        +
        +// no_rows fails when the response is rows
        +session.query("INSERT INTO ks.tab (a) VALUES (0)", &[]).await?.result_not_rows()?;
        +
        +
        +

        For more see QueryResult

        +
        +

        NULL values

        +

        NULL values will return an error when parsed as a Rust type. +To properly handle NULL values parse column as an Option<>:

        +
        use scylla::IntoTypedRows;
        +
        +// Parse row as two columns containing an int and text which might be null
        +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
        +    for row in rows.into_typed::<(i32, Option<String>)>() {
        +        let (int_value, str_or_null): (i32, Option<String>) = row?;
        +    }
        +}
        +
        +
        +
        +
        +

        Parsing row as a custom struct

        +

        It is possible to receive row as a struct with fields matching the columns.
        +The struct must:

        +
          +
        • have the same number of fields as the number of queried columns

        • +
        • have field types matching the columns being received

        • +
        • derive FromRow

        • +
        +

        Field names don’t need to match column names.

        +
        use scylla::IntoTypedRows;
        +use scylla::macros::FromRow;
        +use scylla::frame::response::cql_to_rust::FromRow;
        +
        +#[derive(FromRow)]
        +struct MyRow {
        +    age: i32,
        +    name: Option<String>
        +}
        +
        +// Parse row as two columns containing an int and text which might be null
        +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
        +    for row in rows.into_typed::<MyRow>() {
        +        let my_row: MyRow = row?;
        +    }
        +}
        +
        +
        +
        +
        +

        Other data types

        +

        For parsing other data types see Data Types

        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/schema-agreement.html b/stable/queries/schema-agreement.html new file mode 100644 index 0000000000..449d47f7ba --- /dev/null +++ b/stable/queries/schema-agreement.html @@ -0,0 +1,671 @@ + + + + + + + + + + + + + Schema agreement | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Schema agreement

        +

        Sometimes after performing queries some nodes have not been updated, so we need a mechanism that checks if every node have agreed on schema version.

        +
        +

        Automated awaiting schema agreement

        +

        The driver automatically awaits schema agreement after a schema-altering query is executed. +Waiting for schema agreement more than necessary is never a bug, but might slow down applications which do a lot of schema changes (e.g. a migration). +For instance, in case where somebody wishes to create a keyspace and then a lot of tables in it, it makes sense only to wait after creating a keyspace +and after creating all the tables rather than after every query. Therefore, the said behaviour can be disabled:

        +
        let session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .auto_await_schema_agreement(false)
        +    .build()
        +    .await?;
        +
        +
        +
        +
        +

        Manually awaiting schema agreement

        +

        Session::await_schema_agreement returns a Future that can be awaited as long as schema is not in an agreement. +However, it won’t wait forever; SessionConfig defines a timeout that limits the time of waiting. If the timeout elapses, +the return value is Err(QueryError::RequestTimeout), otherwise it is Ok(schema_version).

        +
        session.await_schema_agreement().await?;
        +
        +
        +
        +
        +

        Interval of checking for schema agreement

        +

        If the schema is not agreed upon, the driver sleeps for a duration before checking it again. The default value is 200 milliseconds, +but it can be changed with SessionBuilder::schema_agreement_interval.

        +
        SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .schema_agreement_interval(Duration::from_secs(1))
        +    .build()
        +    .await?;
        +
        +
        +
        +
        +

        Checking if schema is in agreement now

        +

        If you want to check if schema is in agreement now, without retrying after failure, you can use Session::check_schema_agreement function.

        +
        if session.check_schema_agreement().await?.is_some() {
        +    println!("SCHEMA AGREED");
        +} else {
        +    println!("SCHEMA IS NOT IN AGREEMENT");
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/simple.html b/stable/queries/simple.html new file mode 100644 index 0000000000..83006ffb99 --- /dev/null +++ b/stable/queries/simple.html @@ -0,0 +1,708 @@ + + + + + + + + + + + + + Simple query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Simple query

        +

        Simple query takes query text and values and simply executes them on a Session:

        +
        // Insert a value into the table
        +let to_insert: i32 = 12345;
        +session
        +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
        +    .await?;
        +
        +
        +
        +

        Warning
        +Don’t use simple query to receive large amounts of data.
        +By default the query is unpaged and might cause heavy load on the cluster.
        +In such cases set a page size and use paged query instead.\

        +

        When page size is set, query will return only the first page of results.

        +
        +
        +

        Warning
        +If the values are not empty, driver first needs to send a PREPARE request +in order to fetch information required to serialize values. This will affect +performance because 2 round trips will be required instead of 1.

        +
        +
        +

        First argument - the query

        +

        As the first argument Session::query takes anything implementing Into<Query>.
        +You can create a query manually to set custom options. For example to change query consistency:

        +
        use scylla::query::Query;
        +use scylla::statement::Consistency;
        +
        +// Create a Query manually to change the Consistency to ONE
        +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
        +my_query.set_consistency(Consistency::One);
        +
        +// Insert a value into the table
        +let to_insert: i32 = 12345;
        +session.query(my_query, (to_insert,)).await?;
        +
        +
        +

        See Query API documentation for more options

        +
        +
        +

        Second argument - the values

        +

        Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.
        +Each ? in query text will be filled with the matching value.

        +

        The easiest way is to pass values using a tuple:

        +
        // Sending an integer and a string using a tuple
        +session
        +    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, 'text2')", (2_i32, "Some text"))
        +    .await?;
        +
        +
        +

        Here the first ? will be filled with 2 and the second with "Some text".

        +
        +

        Never pass values by adding strings, this could lead to SQL Injection

        +
        +

        See Query values for more information about sending values in queries

        +
        +
        +

        Query result

        +

        Session::query returns QueryResult with rows represented as Option<Vec<Row>>.
        +Each row can be parsed as a tuple of rust types using rows_typed:

        +
        use scylla::IntoTypedRows;
        +
        +// Query rows from the table and print them
        +let result = session.query("SELECT a FROM ks.tab", &[]).await?;
        +let mut iter = result.rows_typed::<(i32,)>()?;
        +while let Some(read_row) = iter.next().transpose()? {
        +    println!("Read a value from row: {}", read_row.0);
        +}
        +
        +
        +
        +

        In cases where page size is set, simple query returns only a single page of results.
        +To receive all pages use a paged query instead.\

        +
        +

        See Query result for more information about handling query results

        +
        +
        +

        Performance

        +

        Simple queries should not be used in places where performance matters.
        +If performance matters use a Prepared query instead.

        +

        With simple query the database has to parse query text each time it’s executed, which worsens performance.\

        +

        Additionally token and shard aware load balancing does not work with simple queries. They are sent to random nodes.

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/timeouts.html b/stable/queries/timeouts.html new file mode 100644 index 0000000000..9500a345f8 --- /dev/null +++ b/stable/queries/timeouts.html @@ -0,0 +1,657 @@ + + + + + + + + + + + + + Query timeouts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Query timeouts

        +

        Query execution time can be limited by setting a request timeout. If a query does not complete +in the given time, then QueryError::RequestTimeout is returned by the driver immediately, +so that application logic can continue operating, but the query may still be in progress on the server.

        +

        As a side note, if one wishes custom server-side timeouts (i.e. actual interruption of query processing), +one can use aUSING TIMEOUT <duration> directive supported in ScyllaDB +(but not in Cassandra).

        +

        Timeout can be set globally (per session) or locally (for given statement). +The default per-session timeout is currently 30s. +It is possible to turn off timeouts completely by providing None as timeout when building Session. +However, setting per-statement timeout to None results in falling back to per-session timeout.

        +
        use scylla::{Session, SessionBuilder, query::Query};
        +use scylla::transport::ExecutionProfile;
        +use std::time::Duration;
        +
        +let uri = std::env::var("SCYLLA_URI")
        +    .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
        +
        +let no_timeout_profile_handle = ExecutionProfile::builder()
        +    .request_timeout(None) // no timeout
        +    .build()
        +    .into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node(uri)
        +    .default_execution_profile_handle(no_timeout_profile_handle) // no per-session timeout
        +    .build()
        +    .await?;
        +
        +// This query, having no timeout, could block indefinitely if a queried node hangs.
        +session
        +    .query("TRUNCATE keyspace.table", ())
        +    .await?;
        +
        +let three_sec_timeout_profile_handle = ExecutionProfile::builder()
        +    .request_timeout(Some(Duration::from_secs(3))) // no timeout
        +    .build()
        +    .into_handle();
        +
        +// The below query will last for no more than 3 seconds, yielding a RequestTimeout error
        +// if no response arrives until then.
        +let mut query: Query = "TRUNCATE keyspace.table".into();
        +query.set_execution_profile_handle(Some(three_sec_timeout_profile_handle));
        +session
        +    .query(query, ())
        +    .await?;
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/usekeyspace.html b/stable/queries/usekeyspace.html new file mode 100644 index 0000000000..49e9838f7a --- /dev/null +++ b/stable/queries/usekeyspace.html @@ -0,0 +1,691 @@ + + + + + + + + + + + + + USE keyspace | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        USE keyspace

        +

        Using a keyspace allows to omit keyspace name in queries.

        +

        For example in cqlsh one could write:

        +
        cqlsh> SELECT * FROM my_keyspace.table;
        +
        + a     | b     |
        +-------+-------+
        + 12345 | 54321 |
        +
        +(1 rows)
        +cqlsh> USE my_keyspace;
        +cqlsh:my_keyspace> SELECT * FROM table;
        +
        + a     | b     |
        +-------+-------+
        + 12345 | 54321 |
        +
        +(1 rows)
        +
        +
        +

        Tables from other keyspaces can still easily be accessed by using their keyspace names.

        +
        cqlsh:my_keyspace> SELECT * FROM other_keyspace.other_table;
        +
        +
        +

        In the driver this can be achieved using Session::use_keyspace:

        +
        session
        +    .query("INSERT INTO my_keyspace.tab (a) VALUES ('test1')", &[])
        +    .await?;
        +
        +session.use_keyspace("my_keyspace", false).await?;
        +
        +// Now we can omit keyspace name in the query
        +session
        +    .query("INSERT INTO tab (a) VALUES ('test2')", &[])
        +    .await?;
        +
        +
        +

        The first argument is the keyspace name.
        +The second argument states whether this name is case sensitive.

        +

        It is also possible to send raw use keyspace query using Session::query instead of Session::use_keyspace such as:

        +
        session.query("USE my_keyspace", &[]).await?;
        +
        +
        +

        This method has a slightly worse latency than Session::use_keyspace - there are two roundtrips needed instead of one. +Therefore, Session::use_keyspace is the preferred method for setting keyspaces.

        +
        +

        Multiple use queries at once

        +

        Don’t run multiple use_keyspace queries at once. +This could end up with half of connections using one keyspace and the other half using the other.

        +
        +
        +

        Case sensitivity

        +

        In CQL a keyspace name can be case insensitive (without ") or case sensitive (with ").
        +If the second argument to use_keyspace is set to true this keyspace name will be wrapped in ".
        +It is best to avoid the problem altogether and just not create two keyspaces with the same name but different cases.

        +

        Let’s see what happens when there are two keyspaces with the same name but different cases: my_keyspace and MY_KEYSPACE:

        +
        // lowercase name without case sensitivity will use my_keyspace
        +session.use_keyspace("my_keyspace", false).await?;
        +
        +// lowercase name with case sensitivity will use my_keyspace
        +session.use_keyspace("my_keyspace", true).await?;
        +
        +// uppercase name without case sensitivity will use my_keyspace
        +session.use_keyspace("MY_KEYSPACE", false).await?;
        +
        +// uppercase name with case sensitivity will use MY_KEYSPACE
        +session.use_keyspace("MY_KEYSPACE", true).await?;
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/queries/values.html b/stable/queries/values.html new file mode 100644 index 0000000000..8de34d4bbc --- /dev/null +++ b/stable/queries/values.html @@ -0,0 +1,747 @@ + + + + + + + + + + + + + Query values | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Query values

        +

        Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.
        +Each ? in query text will be filled with the matching value.

        +
        +

        Never pass values by adding strings, this could lead to SQL Injection

        +
        +

        Each list of values to send in a query must implement the trait SerializeRow.
        +By default this can be a slice &[], a tuple () (max 16 elements) of values to send, +or a custom struct which derives from SerializeRow.

        +

        A few examples:

        +
        // Empty slice means that there are no values to send
        +session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?;
        +
        +// Empty tuple/unit also means that there are no values to send
        +session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?;
        +
        +// Sending three integers using a slice:
        +session
        +    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref())
        +    .await?;
        +
        +// Sending an integer and a string using a tuple
        +session
        +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text"))
        +    .await?;
        +
        +// Sending an integer and a string using a named struct.
        +// Names of fields must match names of columns in request,
        +// but having them in the same order is not required.
        +// If the fields are in the same order, you can use attribute:
        +// `#[scylla(flavor = "enforce_order")]`
        +// in order to skip sorting the fields and just check if they
        +// are in the same order. See documentation of this macro
        +// for more information.
        +#[derive(SerializeRow)]
        +struct IntString {
        +    a: i32,
        +    b: String,
        +}
        +
        +let int_string = IntString {
        +    a: 42_i32,
        +    b: "hello".to_owned(),
        +};
        +
        +session
        +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string)
        +    .await?;
        +
        +// You can use named bind markers in query if you want
        +// your names in struct to be different than column names.
        +#[derive(SerializeRow)]
        +struct IntStringCustom {
        +    first_value: i32,
        +    second_value: String,
        +}
        +
        +let int_string_custom = IntStringCustom {
        +    first_value: 42_i32,
        +    second_value: "hello".to_owned(),
        +};
        +
        +session
        +    .query("INSERT INTO ks.tab (a, b) VALUES(:first_value, :second_value)", int_string_custom)
        +    .await?;
        +
        +// Sending a single value as a tuple requires a trailing coma (Rust syntax):
        +session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?;
        +
        +// Each value can also be sent using a reference:
        +session
        +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text"))
        +    .await?;
        +
        +// A map of named values can also be provided:
        +let mut vals: HashMap<&str, CqlValue> = HashMap::new();
        +vals.insert("avalue", CqlValue::Text("hello".to_string()));
        +vals.insert("bvalue", CqlValue::Int(17));
        +session
        +    .query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals)
        +    .await?;
        +
        +
        +
        +

        NULL values

        +

        Null values can be sent using Option<> - sending a None will make the value NULL:

        +
        let null_i32: Option<i32> = None;
        +session
        +    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
        +    .await?;
        +
        +
        +
        +
        +

        Unset values

        +

        When performing an insert with values which might be NULL, it’s better to use Unset.
        +Database treats inserting NULL as a delete operation and will generate a tombstone. +Using Unset results in better performance:

        +
        use scylla::frame::value::{MaybeUnset, Unset};
        +
        +// Inserting a null results in suboptimal performance
        +let null_i32: Option<i32> = None;
        +session
        +    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
        +    .await?;
        +
        +// Using MaybeUnset enum is better
        +let unset_i32: MaybeUnset<i32> = MaybeUnset::Unset;
        +session
        +    .query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,))
        +    .await?;
        +
        +// If we are sure that a value should be unset we can simply use Unset
        +session
        +    .query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,))
        +    .await?;
        +
        +
        +

        See the issue for more information about Unset

        +
        +
        +

        Other data types

        +

        See Data Types for instructions on sending other data types

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/quickstart/create-project.html b/stable/quickstart/create-project.html new file mode 100644 index 0000000000..80442b952f --- /dev/null +++ b/stable/quickstart/create-project.html @@ -0,0 +1,639 @@ + + + + + + + + + + + + + Creating a project | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Creating a project

        +

        To create a new project run:

        +
        cargo new myproject
        +
        +
        +

        In Cargo.toml add useful dependencies:

        +
        [dependencies]
        +scylla = "0.13"
        +tokio = { version = "1.12", features = ["full"] }
        +futures = "0.3.6"
        +uuid = "1.0"
        +bigdecimal = "0.4"
        +num-bigint = "0.3"
        +tracing = "0.1.36"
        +tracing-subscriber = { version = "0.3.14", features = ["env-filter"] }
        +
        +
        +

        In main.rs put:

        +
        use scylla::Session;
        +
        +#[tokio::main]
        +async fn main() {
        +    println!("Hello scylla!");
        +}
        +
        +
        +

        Now running cargo run should print:

        +
        Hello scylla!
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/quickstart/example.html b/stable/quickstart/example.html new file mode 100644 index 0000000000..b2de22ffaa --- /dev/null +++ b/stable/quickstart/example.html @@ -0,0 +1,660 @@ + + + + + + + + + + + + + Connecting and running a simple query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Connecting and running a simple query

        +

        Now everything is ready to use the driver. +Here is a small example:

        +
        use scylla::{IntoTypedRows, Session, SessionBuilder};
        +use std::error::Error;
        +
        +#[tokio::main]
        +async fn main() -> Result<(), Box<dyn Error>> {
        +    // Create a new Session which connects to node at 127.0.0.1:9042
        +    // (or SCYLLA_URI if specified)
        +    let uri = std::env::var("SCYLLA_URI")
        +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
        +
        +    let session: Session = SessionBuilder::new()
        +        .known_node(uri)
        +        .build()
        +        .await?;
        +
        +    // Create an example keyspace and table
        +    session
        +        .query(
        +            "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \
        +            {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}",
        +            &[],
        +        )
        +        .await?;
        +
        +    session
        +        .query(
        +            "CREATE TABLE IF NOT EXISTS ks.extab (a int primary key)",
        +            &[],
        +        )
        +        .await?;
        +
        +    // Insert a value into the table
        +    let to_insert: i32 = 12345;
        +    session
        +        .query("INSERT INTO ks.extab (a) VALUES(?)", (to_insert,))
        +        .await?;
        +
        +    // Query rows from the table and print them
        +    let result = session.query("SELECT a FROM ks.extab", &[]).await?;
        +    let mut iter = result.rows_typed::<(i32,)>()?;
        +    while let Some(read_row) = iter.next().transpose()? {
        +        println!("Read a value from row: {}", read_row.0);
        +    }
        +
        +    Ok(())
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/quickstart/quickstart.html b/stable/quickstart/quickstart.html new file mode 100644 index 0000000000..1e54a1cc72 --- /dev/null +++ b/stable/quickstart/quickstart.html @@ -0,0 +1,613 @@ + + + + + + + + + + + + + Quick Start | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Quick Start

        +

        In this chapter we will set up a Rust project and run a few simple queries.

        +

        Topics Include:

        + +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/quickstart/scylla-docker.html b/stable/quickstart/scylla-docker.html new file mode 100644 index 0000000000..51a5f4099d --- /dev/null +++ b/stable/quickstart/scylla-docker.html @@ -0,0 +1,642 @@ + + + + + + + + + + + + + Running Scylla using Docker | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Running Scylla using Docker

        +

        To make queries we will need a running Scylla instance. The easiest way is to use a Docker image.
        +Please install Docker if it’s not installed.

        +
        +

        Running scylla

        +

        To start Scylla run:

        +
        # on Linux sudo might be required
        +docker run --rm -it -p 9042:9042 scylladb/scylla --smp 2
        +
        +
        +

        Docker will download the image, then after minute or two there should be a message like:

        +
        Starting listening for CQL clients on 172.17.0.2:9042
        +
        +
        +

        This means that Scylla is ready to receive queries

        +

        To stop this instance press Ctrl + C

        +
        +
        +

        More information

        +

        More information about this image can be found on dockerhub

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/retry-policy/default.html b/stable/retry-policy/default.html new file mode 100644 index 0000000000..91f7e90682 --- /dev/null +++ b/stable/retry-policy/default.html @@ -0,0 +1,688 @@ + + + + + + + + + + + + + Default retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Default retry policy

        +

        This is the retry policy used by default. It retries when there is a high chance that it might help.
        +This policy is based on the one in DataStax Java Driver. +The behaviour is the same.

        +
        +

        Examples

        +

        To use in Session:

        +
        use scylla::{Session, SessionBuilder};
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::retry_policy::DefaultRetryPolicy;
        +
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .default_execution_profile_handle(handle)
        +    .build()
        +    .await?;
        +
        +
        +

        To use in a simple query:

        +
        use scylla::query::Query;
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::retry_policy::DefaultRetryPolicy;
        +
        +// Create a Query manually and set the retry policy
        +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
        +my_query.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new())));
        +
        +// You can also set retry policy in an execution profile
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +my_query.set_execution_profile_handle(Some(handle));
        +
        +// Run the query using this retry policy
        +let to_insert: i32 = 12345;
        +session.query(my_query, (to_insert,)).await?;
        +
        +
        +

        To use in a prepared query:

        +
        use scylla::prepared_statement::PreparedStatement;
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::retry_policy::DefaultRetryPolicy;
        +
        +// Create PreparedStatement manually and set the retry policy
        +let mut prepared: PreparedStatement = session
        +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
        +    .await?;
        +prepared.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new())));
        +
        +// You can also set retry policy in an execution profile
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +prepared.set_execution_profile_handle(Some(handle));
        +
        +// Run the query using this retry policy
        +let to_insert: i32 = 12345;
        +session.execute(&prepared, (to_insert,)).await?;
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/retry-policy/downgrading-consistency.html b/stable/retry-policy/downgrading-consistency.html new file mode 100644 index 0000000000..13e1180c04 --- /dev/null +++ b/stable/retry-policy/downgrading-consistency.html @@ -0,0 +1,729 @@ + + + + + + + + + + + + + Downgrading consistency retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Downgrading consistency retry policy

        +

        A retry policy that sometimes retries with a lower consistency level than the one initially +requested. +BEWARE: this policy may retry queries using a lower consistency level than the one +initially requested. By doing so, it may break consistency guarantees. In other words, if you use +this retry policy, there are cases (documented below) where a read at Consistency::Quorum may +not see a preceding write at Consistency::Quorum. Do not use this policy unless you have +understood the cases where this can happen and are ok with that. It is also highly recommended to +always log the occurrences of such consistency breaks. +This policy implements the same retries than the DefaultRetryPolicy policy. But on top +of that, it also retries in the following cases:

        +
          +
        • On a read timeout: if the number of replicas that responded is greater than one, but lower +than is required by the requested consistency level, the operation is retried at a lower +consistency level.

        • +
        • On a write timeout: if the operation is a WriteType::UnloggedBatch and at least one +replica acknowledged the write, the operation is retried at a lower consistency level. +Furthermore, for other operations, if at least one replica acknowledged the write, the +timeout is ignored.

        • +
        • On an unavailable exception: if at least one replica is alive, the operation is retried at +a lower consistency level.

        • +
        +

        The lower consistency level to use for retries is determined by the following rules:

        +
          +
        • if more than 3 replicas responded, use Consistency::Three.

        • +
        • if 1, 2 or 3 replicas responded, use the corresponding level Consistency::One, Consistency::Two or +Consistency::Three.

        • +
        +

        Note that if the initial consistency level was Consistency::EachQuorum, Scylla returns the number +of live replicas in the datacenter that failed to reach consistency, not the overall +number in the cluster. Therefore if this number is 0, we still retry at Consistency::One, on the +assumption that a host may still be up in another datacenter. +The reasoning being this retry policy is the following one. If, based on the information the +Scylla coordinator node returns, retrying the operation with the initially requested +consistency has a chance to succeed, do it. Otherwise, if based on this information we know +the initially requested consistency level cannot be achieved currently, then:

        +
          +
        • For writes, ignore the exception (thus silently failing the consistency requirement) if we +know the write has been persisted on at least one replica.

        • +
        • For reads, try reading at a lower consistency level (thus silently failing the consistency +requirement). +In other words, this policy implements the idea that if the requested consistency level cannot be +achieved, the next best thing for writes is to make sure the data is persisted, and that reading +something is better than reading nothing, even if there is a risk of reading stale data.

        • +
        +

        This policy is based on the one in DataStax Java Driver. +The behaviour is the same.

        +
        +

        Examples

        +

        To use in Session:

        +
        use scylla::{Session, SessionBuilder};
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
        +
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .default_execution_profile_handle(handle)
        +    .build()
        +    .await?;
        +
        +
        +

        To use in a simple query:

        +
        use scylla::query::Query;
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
        +
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +
        +// Create a Query manually and set the retry policy
        +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
        +my_query.set_execution_profile_handle(Some(handle));
        +
        +// Run the query using this retry policy
        +let to_insert: i32 = 12345;
        +session.query(my_query, (to_insert,)).await?;
        +
        +
        +

        To use in a prepared query:

        +
        use scylla::prepared_statement::PreparedStatement;
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
        +
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +
        +// Create PreparedStatement manually and set the retry policy
        +let mut prepared: PreparedStatement = session
        +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
        +    .await?;
        +
        +prepared.set_execution_profile_handle(Some(handle));
        +
        +
        +// Run the query using this retry policy
        +let to_insert: i32 = 12345;
        +session.execute(&prepared, (to_insert,)).await?;
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/retry-policy/fallthrough.html b/stable/retry-policy/fallthrough.html new file mode 100644 index 0000000000..71a81f8d2b --- /dev/null +++ b/stable/retry-policy/fallthrough.html @@ -0,0 +1,683 @@ + + + + + + + + + + + + + Fallthrough retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Fallthrough retry policy

        +

        The FalthroughRetryPolicy never retries, returns errors straight to the user. Useful for debugging.

        +
        +

        Examples

        +

        To use in Session:

        +
        use scylla::{Session, SessionBuilder};
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::retry_policy::FallthroughRetryPolicy;
        +
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .default_execution_profile_handle(handle)
        +    .build()
        +    .await?;
        +
        +
        +

        To use in a simple query:

        +
        use scylla::query::Query;
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::retry_policy::FallthroughRetryPolicy;
        +
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +
        +// Create a Query manually and set the retry policy
        +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
        +my_query.set_execution_profile_handle(Some(handle));
        +
        +// Run the query using this retry policy
        +let to_insert: i32 = 12345;
        +session.query(my_query, (to_insert,)).await?;
        +
        +
        +

        To use in a prepared query:

        +
        use scylla::prepared_statement::PreparedStatement;
        +use scylla::transport::ExecutionProfile;
        +use scylla::transport::retry_policy::FallthroughRetryPolicy;
        +
        +let handle = ExecutionProfile::builder()
        +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
        +    .build()
        +    .into_handle();
        +
        +// Create PreparedStatement manually and set the retry policy
        +let mut prepared: PreparedStatement = session
        +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
        +    .await?;
        +
        +prepared.set_execution_profile_handle(Some(handle));
        +
        +// Run the query using this retry policy
        +let to_insert: i32 = 12345;
        +session.execute(&prepared, (to_insert,)).await?;
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/retry-policy/retry-policy.html b/stable/retry-policy/retry-policy.html new file mode 100644 index 0000000000..8e36f8a7bb --- /dev/null +++ b/stable/retry-policy/retry-policy.html @@ -0,0 +1,654 @@ + + + + + + + + + + + + + Retry policy configuration | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Retry policy configuration

        +

        After a query fails the driver might decide to retry it based on its Retry Policy and the query itself. +Retry policy can be configured for Session or just for a single query.

        +
        +

        Retry policies

        +

        By default there are three retry policies:

        + +

        It’s possible to implement a custom Retry Policy by implementing the traits RetryPolicy and RetrySession.

        +
        +
        +

        Query idempotence

        +

        A query is idempotent if it can be applied multiple times without changing the result of the initial application

        +

        Specifying that a query is idempotent increases the chances that it will be retried in case of failure. +Idempotent queries can be retried in situations where retrying non idempotent queries would be dangerous.

        +

        Idempotence has to be specified manually, the driver is not able to figure it out by itself.

        +
        use scylla::query::Query;
        +use scylla::prepared_statement::PreparedStatement;
        +
        +// Specify that a Query is idempotent
        +let mut my_query: Query = Query::new("SELECT a FROM ks.tab");
        +my_query.set_is_idempotent(true);
        +
        +
        +// Specify that a PreparedStatement is idempotent
        +let mut prepared: PreparedStatement = session
        +    .prepare("SELECT a FROM ks.tab")
        +    .await?;
        +
        +prepared.set_is_idempotent(true);
        +
        +
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/schema/schema.html b/stable/schema/schema.html new file mode 100644 index 0000000000..5aef2cb677 --- /dev/null +++ b/stable/schema/schema.html @@ -0,0 +1,669 @@ + + + + + + + + + + + + + Schema | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + + + +
        +

        Schema

        +

        The driver is capable of fetching database schema and presenting it to its users.

        +
        +

        Fetching schema

        +

        Fetching database schema occurs periodically, but it can also be done on-demand. In order to fetch the newest database schema, one can call refresh_metadata() on a Session instance:

        +
        #[tokio::main]
        +async fn main() -> Result<(), Box<dyn Error>> {
        +    let uri = std::env::var("SCYLLA_URI")
        +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
        +
        +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
        +    // Schema metadata will be fetched below
        +    session.refresh_metadata().await?;
        +    Ok(())
        +}
        +
        +
        +
        +
        +

        Inspecting schema

        +

        Once fetched, a snapshot of cluster’s schema can be examined. The following information can be obtained:

        +
          +
        • keyspace

          +
            +
          • tables belonging to the keyspace

          • +
          • materialized views belonging to the keyspace

          • +
          • replication strategy

          • +
          • user-defined types

          • +
          +
        • +
        • table/view

          +
            +
          • primary key definition

          • +
          • columns

          • +
          • partitioner type

          • +
          +
        • +
        +

        Example showing how to print obtained schema information:

        +
        #[tokio::main]
        +async fn main() -> Result<(), Box<dyn Error>> {
        +    let uri = std::env::var("SCYLLA_URI")
        +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
        +
        +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
        +    // Schema metadata will be fetched below
        +    session.refresh_metadata().await?;
        +
        +    let cluster_data = &session.get_cluster_data();
        +    let keyspaces = &cluster_data.get_keyspace_info();
        +
        +    for (keyspace_name, keyspace_info) in keyspaces.iter() {
        +        println!("Keyspace {}:", keyspace_name);
        +        println!("\tTables: {:#?}", keyspace_info.tables);
        +        println!("\tViews: {:#?}", keyspace_info.views);
        +        println!("\tUDTs: {:#?}", keyspace_info.user_defined_types);
        +    }
        +
        +    Ok(())
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/search.html b/stable/search.html new file mode 100644 index 0000000000..b8e4c6d401 --- /dev/null +++ b/stable/search.html @@ -0,0 +1,588 @@ + + + + + + + + + + + + + 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 0000000000..7abe38f4fc --- /dev/null +++ b/stable/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["connecting/authentication", "connecting/compression", "connecting/connecting", "connecting/tls", "contents", "data-types/blob", "data-types/collections", "data-types/counter", "data-types/data-types", "data-types/date", "data-types/decimal", "data-types/duration", "data-types/inet", "data-types/primitive", "data-types/text", "data-types/time", "data-types/timestamp", "data-types/timeuuid", "data-types/tuple", "data-types/udt", "data-types/uuid", "data-types/varint", "execution-profiles/create-and-use", "execution-profiles/execution-profiles", "execution-profiles/maximal-example", "execution-profiles/priority", "execution-profiles/remap", "index", "load-balancing/default-policy", "load-balancing/load-balancing", "logging/logging", "metrics/metrics", "migration-guides/0.11-serialization", "migration-guides/migration-guides", "queries/batch", "queries/lwt", "queries/paged", "queries/prepared", "queries/queries", "queries/result", "queries/schema-agreement", "queries/simple", "queries/timeouts", "queries/usekeyspace", "queries/values", "quickstart/create-project", "quickstart/example", "quickstart/quickstart", "quickstart/scylla-docker", "retry-policy/default", "retry-policy/downgrading-consistency", "retry-policy/fallthrough", "retry-policy/retry-policy", "schema/schema", "speculative-execution/percentile", "speculative-execution/simple", "speculative-execution/speculative", "tracing/basic", "tracing/paged", "tracing/prepare", "tracing/query-history", "tracing/tracing"], "filenames": ["connecting/authentication.md", "connecting/compression.md", "connecting/connecting.md", "connecting/tls.md", "contents.rst", "data-types/blob.md", "data-types/collections.md", "data-types/counter.md", "data-types/data-types.md", "data-types/date.md", "data-types/decimal.md", "data-types/duration.md", "data-types/inet.md", "data-types/primitive.md", "data-types/text.md", "data-types/time.md", "data-types/timestamp.md", "data-types/timeuuid.md", "data-types/tuple.md", "data-types/udt.md", "data-types/uuid.md", "data-types/varint.md", "execution-profiles/create-and-use.md", "execution-profiles/execution-profiles.md", "execution-profiles/maximal-example.md", "execution-profiles/priority.md", "execution-profiles/remap.md", "index.md", "load-balancing/default-policy.md", "load-balancing/load-balancing.md", "logging/logging.md", "metrics/metrics.md", "migration-guides/0.11-serialization.md", "migration-guides/migration-guides.md", "queries/batch.md", "queries/lwt.md", "queries/paged.md", "queries/prepared.md", "queries/queries.md", "queries/result.md", "queries/schema-agreement.md", "queries/simple.md", "queries/timeouts.md", "queries/usekeyspace.md", "queries/values.md", "quickstart/create-project.md", "quickstart/example.md", "quickstart/quickstart.md", "quickstart/scylla-docker.md", "retry-policy/default.md", "retry-policy/downgrading-consistency.md", "retry-policy/fallthrough.md", "retry-policy/retry-policy.md", "schema/schema.md", "speculative-execution/percentile.md", "speculative-execution/simple.md", "speculative-execution/speculative.md", "tracing/basic.md", "tracing/paged.md", "tracing/prepare.md", "tracing/query-history.md", "tracing/tracing.md"], "titles": ["Authentication", "Compression", "Connecting to the cluster", "TLS", "<no title>", "Blob", "List, Set, Map", "Counter", "Data Types", "Date", "Decimal", "Duration", "Inet", "Bool, Tinyint, Smallint, Int, Bigint, Float, Double", "Ascii, Text, Varchar", "Time", "Timestamp", "Timeuuid", "Tuple", "User defined types", "Uuid", "Varint", "Creating a profile and setting it", "Execution profiles", "All options supported by a profile", "Priorities of execution settings", "Remapping execution profile handles", "Scylla Rust Driver", "DefaultPolicy", "Load balancing", "Logging", "Driver metrics", "Adjusting code to changes in serialization API introduced in 0.11", "Migration guides", "Batch statement", "Lightweight transaction (LWT) query", "Paged query", "Prepared query", "Making queries", "Query result", "Schema agreement", "Simple query", "Query timeouts", "USE keyspace", "Query values", "Creating a project", "Connecting and running a simple query", "Quick Start", "Running Scylla using Docker", "Default retry policy", "Downgrading consistency retry policy", "Fallthrough retry policy", "Retry policy configuration", "Schema", "Percentile speculative execution", "Simple speculative execution", "Speculative execution", "Tracing a simple/prepared/batch query", "Tracing a paged query", "Tracing Session::prepare", "Query Execution History", "Query tracing"], "terms": {"driver": [0, 1, 2, 3, 8, 19, 28, 29, 30, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 49, 50, 52, 53, 56, 61], "support": [0, 1, 2, 3, 9, 15, 16, 21, 28, 32, 38, 42, 61], "both": [0, 32], "usernam": [0, 2], "password": [0, 2], "defin": [0, 8, 26, 32, 35, 40, 53], "user": [0, 8, 10, 21, 28, 32, 51, 52, 53], "To": [0, 3, 10, 19, 21, 22, 28, 29, 30, 32, 37, 39, 41, 45, 48, 49, 50, 51, 54, 55, 60], "specifi": [0, 1, 2, 25, 28, 34, 37, 41, 44, 46, 52, 60], "method": [0, 2, 28, 29, 32, 43, 56], "sessionbuild": [0, 1, 2, 3, 22, 25, 26, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "scylla": [0, 1, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 32, 34, 35, 36, 37, 38, 39, 41, 42, 44, 45, 46, 47, 49, 50, 51, 52, 54, 55, 57, 58, 59, 60, 61], "session": [0, 1, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 29, 30, 31, 32, 34, 35, 36, 39, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61], "let": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 30, 31, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "new": [0, 1, 2, 3, 6, 12, 16, 22, 24, 25, 26, 28, 29, 30, 34, 35, 36, 40, 41, 42, 44, 45, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "known_nod": [0, 1, 2, 3, 22, 25, 26, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "127": [0, 1, 2, 3, 12, 22, 25, 26, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55, 60], "0": [0, 1, 2, 3, 7, 10, 12, 13, 16, 18, 22, 25, 26, 30, 33, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 53, 54, 55, 60], "1": [0, 1, 2, 3, 5, 6, 9, 11, 12, 15, 16, 18, 22, 25, 26, 28, 30, 32, 34, 36, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 53, 54, 55, 60], "9042": [0, 1, 2, 22, 25, 26, 30, 40, 42, 46, 48, 49, 50, 51, 53, 54, 55, 60], "myusernam": 0, "mypassword": 0, "build": [0, 1, 2, 3, 22, 24, 25, 26, 28, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "await": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 29, 30, 34, 35, 36, 37, 39, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "A": [0, 32, 34, 35, 44, 50, 52, 58, 60], "implement": [0, 28, 29, 34, 41, 44, 50, 52, 60], "authenticatorsess": 0, "an": [0, 1, 2, 3, 9, 13, 15, 16, 22, 23, 25, 27, 28, 29, 35, 36, 39, 40, 41, 44, 46, 49, 50, 56, 60], "instanc": [0, 2, 23, 28, 29, 40, 48, 53], "creat": [0, 2, 3, 19, 23, 29, 30, 34, 35, 37, 40, 41, 43, 46, 47, 49, 50, 51, 57, 58, 60], "per": [0, 2, 29, 42], "so": [0, 2, 3, 25, 26, 28, 29, 32, 35, 40, 42, 50], "also": [0, 2, 16, 19, 25, 26, 27, 28, 29, 32, 43, 44, 49, 50, 52, 53], "necessari": [0, 40], "authenticatorprovid": 0, "final": [0, 32, 60], "make": [0, 10, 21, 27, 29, 32, 35, 40, 44, 48, 50], "authenticator_provid": 0, "byte": 0, "bufmut": [0, 32], "bytesmut": 0, "async_trait": 0, "autherror": 0, "struct": [0, 7, 8, 19, 32, 37, 44, 60], "customauthent": 0, "impl": [0, 32], "handl": [0, 2, 19, 22, 23, 29, 39, 41, 49, 50, 51, 54, 55], "challeng": 0, "initi": [0, 29, 50, 52], "inform": [0, 2, 8, 16, 19, 29, 32, 34, 36, 41, 44, 50, 53, 60, 61], "contain": [0, 2, 27, 29, 34, 35, 39, 57, 58, 59, 61], "token": [0, 29, 34, 37, 41], "paramet": [0, 19, 35, 60], "protocol": [0, 32], "specif": [0, 25, 28, 29, 35, 61], "It": [0, 1, 3, 9, 15, 16, 28, 29, 32, 35, 36, 39, 42, 43, 49, 50, 52, 55, 61], "mai": [0, 28, 32, 42, 50], "null": [0, 19], "empti": [0, 34, 36, 41, 44], "async": [0, 1, 2, 30, 36, 45, 46, 53], "fn": [0, 1, 2, 30, 32, 45, 46, 53], "evaluate_challeng": 0, "mut": [0, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 32, 34, 35, 36, 37, 41, 42, 44, 46, 49, 50, 51, 52, 57, 58, 59, 60], "self": [0, 2, 32], "_token": 0, "option": [0, 19, 23, 25, 27, 29, 32, 35, 39, 41, 44, 57], "u8": [0, 5, 8], "result": [0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 30, 32, 34, 36, 37, 38, 42, 44, 46, 52, 53, 59, 60], "vec": [0, 5, 6, 8, 10, 39, 41], "err": [0, 40], "expect": [0, 16, 32], "to_str": [0, 1, 2, 6, 14, 18, 19, 28, 30, 35, 42, 44, 46, 53], "success": [0, 29, 37, 52, 60], "phase": 0, "exchang": 0, "request": [0, 2, 22, 23, 25, 28, 29, 31, 32, 34, 36, 41, 42, 44, 50, 54, 59, 60], "ok": [0, 1, 2, 30, 40, 46, 50, 53], "customauthenticatorprovid": 0, "start_authentication_sess": 0, "_name": 0, "str": [0, 8, 10, 14, 21, 32, 44], "box": [0, 1, 2, 24, 30, 46, 49, 50, 51, 53], "dyn": [0, 1, 2, 30, 46, 53], "respons": [0, 28, 32, 38, 39, 42, 60], "cred": 0, "0cassandra": 0, "cred_length": 0, "20": 0, "put_i32": 0, "put_slic": 0, "as_byt": 0, "some": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 35, 36, 37, 39, 40, 41, 42, 44, 46, 49, 50, 51, 52, 54, 55, 57, 58, 60, 61], "to_vec": 0, "authentication_exampl": 0, "error": [0, 1, 2, 15, 29, 30, 31, 39, 42, 46, 51, 52, 53, 60], "_session": 0, "arc": [0, 2, 24, 29, 49, 54, 55, 60], "By": [1, 2, 28, 32, 34, 37, 41, 44, 50, 52], "default": [1, 2, 19, 22, 24, 25, 28, 29, 30, 34, 35, 37, 40, 41, 42, 44, 52, 56, 57], "doe": [1, 32, 41, 42, 55, 60, 61], "us": [1, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 40, 41, 42, 44, 45, 46, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61], "ani": [1, 2, 9, 10, 15, 16, 19, 21, 23, 25, 31, 32, 35, 36, 37, 60, 61], "connect": [1, 27, 29, 30, 43, 59], "": [1, 2, 3, 9, 15, 16, 19, 25, 26, 28, 29, 32, 34, 35, 36, 37, 39, 41, 43, 44, 48, 52, 53, 60, 61], "possibl": [1, 28, 29, 32, 34, 36, 39, 42, 43, 52, 60, 61], "prefer": [1, 25, 36, 43], "algorithm": 1, "The": [1, 2, 3, 8, 19, 23, 28, 29, 30, 32, 35, 39, 40, 41, 42, 43, 48, 49, 50, 51, 53, 55, 60, 61], "try": [1, 2, 28, 29, 50, 60], "databas": [1, 2, 3, 8, 15, 16, 19, 27, 29, 32, 41, 44, 53, 61], "doesn": [1, 2, 3, 16, 37, 38, 60, 61], "t": [1, 2, 3, 6, 7, 8, 15, 16, 32, 36, 37, 38, 39, 40, 41, 43, 60, 61], "fall": [1, 28, 42], "back": [1, 42], "avail": [1, 9, 15, 16, 21, 25, 28, 30, 38, 55, 56, 61], "snappi": 1, "lz4": 1, "exampl": [1, 2, 3, 8, 19, 27, 29, 30, 32, 34, 37, 41, 43, 44, 46, 47, 53], "enabl": [1, 9, 10, 15, 16, 21, 26, 28, 29, 38, 56, 57, 58, 59, 60], "transport": [1, 22, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55, 58], "std": [1, 2, 3, 6, 8, 10, 12, 21, 22, 24, 28, 29, 30, 42, 46, 53, 54, 55, 60], "tokio": [1, 2, 30, 45, 46, 53], "main": [1, 2, 30, 45, 46, 53], "uri": [1, 2, 29, 30, 42, 46, 53], "env": [1, 2, 30, 42, 45, 46, 53], "var": [1, 2, 30, 42, 46, 53], "scylla_uri": [1, 2, 30, 42, 46, 53], "unwrap_or_els": [1, 2, 30, 42, 46, 53], "_": [1, 2, 30, 32, 36, 42, 46, 53], "i": [2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 23, 25, 27, 28, 29, 30, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 48, 49, 50, 52, 53, 54, 56, 58, 59, 60, 61], "distribut": [2, 28], "which": [2, 3, 10, 17, 21, 23, 25, 28, 29, 30, 32, 34, 36, 37, 39, 40, 41, 44, 46, 57, 60, 61], "mean": [2, 28, 29, 32, 36, 44, 48], "oper": [2, 28, 31, 34, 42, 44, 50, 61], "multipl": [2, 38, 52, 56, 58], "node": [2, 29, 34, 36, 37, 40, 41, 42, 46, 50, 56, 60, 61], "run": [2, 23, 27, 30, 34, 37, 38, 43, 45, 47, 49, 50, 51, 60], "independ": 2, "when": [2, 19, 27, 28, 29, 32, 35, 37, 38, 39, 41, 42, 43, 44, 49, 54, 60, 61], "you": [2, 3, 19, 25, 26, 28, 29, 30, 32, 34, 37, 38, 40, 41, 44, 49, 50, 61], "can": [2, 5, 7, 9, 10, 15, 16, 19, 21, 23, 25, 26, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 48, 49, 50, 52, 53, 56, 60, 61], "few": [2, 27, 39, 44, 47], "known": 2, "time": [2, 8, 22, 24, 28, 32, 40, 41, 42, 52, 54, 55, 60], "durat": [2, 8, 22, 24, 28, 40, 42, 54, 55], "net": [2, 8, 12], "ipaddr": [2, 8, 12], "ipv4addr": [2, 12], "socketaddr": 2, "72": 2, "4321": 2, "localhost": 2, "8000": 2, "connection_timeout": 2, "from_sec": [2, 22, 24, 28, 40, 42], "3": [2, 5, 6, 8, 9, 10, 11, 15, 21, 24, 28, 32, 34, 42, 44, 45, 50, 54, 55], "cluster_metadata_refresh_interv": 2, "10": [2, 3], "known_node_addr": 2, "v4": [2, 12], "9000": 2, "after": [2, 19, 28, 32, 40, 48, 52, 55, 61], "successfulli": [2, 29], "fetch": [2, 27, 36, 41, 58, 61], "topologi": 2, "about": [2, 8, 27, 29, 32, 34, 41, 44, 48, 60, 61], "other": [2, 9, 15, 16, 19, 28, 29, 32, 35, 37, 43, 50, 60], "thi": [2, 19, 23, 26, 27, 28, 29, 30, 32, 34, 36, 37, 38, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 60, 61], "them": [2, 25, 27, 28, 32, 34, 37, 38, 39, 41, 44, 46, 60], "well": [2, 28], "alwai": [2, 25, 35, 37, 50], "onli": [2, 7, 9, 15, 16, 28, 29, 32, 34, 35, 37, 40, 41, 56], "singl": [2, 23, 32, 36, 38, 39, 41, 44, 52, 60], "object": [2, 23, 34], "apllic": 2, "becaus": [2, 3, 29, 36, 41], "veri": [2, 10, 21, 28, 32], "expens": 2, "maintain": 2, "its": [2, 9, 23, 28, 29, 32, 34, 52, 53, 56, 60], "own": [2, 19, 29], "pool": 2, "each": [2, 8, 28, 29, 32, 34, 36, 41, 44, 58, 59, 60], "capabl": [2, 53], "parallel": [2, 38, 60], "rout": [2, 28], "shard": [2, 29, 34, 37, 41], "actual": [2, 32, 42], "data": [2, 19, 27, 28, 29, 32, 34, 37, 41, 50], "unless": [2, 28, 32, 50], "load": [2, 23, 27, 28, 34, 37, 38, 41], "balanc": [2, 23, 27, 28, 34, 37, 38, 41], "polici": [2, 23, 27, 28, 54, 55, 60], "For": [2, 3, 19, 29, 32, 34, 35, 36, 37, 39, 40, 41, 43, 50], "those": [2, 25, 28, 32], "reason": [2, 32, 50], "we": [2, 5, 26, 32, 37, 40, 43, 44, 47, 48, 50, 60, 61], "recommend": [2, 28, 29, 32, 50], "one": [2, 19, 21, 25, 32, 34, 36, 37, 39, 42, 43, 49, 50, 53, 55, 60], "applic": [2, 28, 40, 42, 52], "short": 2, "live": [2, 50], "e": [2, 9, 28, 29, 32, 35, 40, 42], "g": [2, 28, 29, 32, 35, 40], "strongli": [2, 34], "discourag": [2, 34], "great": 2, "perform": [2, 28, 29, 32, 38, 40, 44, 58, 60, 61], "penalti": [2, 36], "costli": 2, "process": [2, 42], "requir": [2, 9, 16, 19, 32, 35, 36, 41, 44, 48, 50], "estabilish": 2, "lot": [2, 40], "tcp": 2, "mani": [2, 34, 38, 60], "thread": 2, "task": 2, "wast": 2, "resourc": 2, "mention": [2, 32], "befor": [2, 9, 28, 32, 34, 37, 38, 40, 56], "itself": [2, 32, 35, 39, 52], "queri": [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 40, 47, 48, 49, 50, 51, 55, 56, 59], "would": [2, 32, 52, 60, 61], "hold": 2, "unnecessarili": 2, "If": [2, 9, 15, 16, 28, 32, 36, 37, 40, 41, 42, 43, 44, 50, 58, 59, 61], "need": [2, 3, 29, 36, 37, 38, 39, 40, 41, 43, 48, 61], "share": [2, 23, 54], "differ": [2, 9, 15, 16, 19, 23, 27, 35, 43, 44], "etc": [2, 27, 60, 61], "all": [2, 16, 22, 23, 26, 27, 28, 30, 32, 34, 37, 38, 40, 41, 52, 58, 59, 60, 61], "take": [2, 32, 34, 36, 37, 41], "hinder": 2, "function": [2, 3, 38, 40], "wai": [2, 23, 26, 36, 37, 39, 41, 48, 61], "refresh": 2, "period": [2, 53], "schema": [2, 27, 32], "everi": [2, 28, 40], "60": 2, "second": [2, 15, 16, 32, 34, 42, 43, 56], "howev": [2, 9, 15, 16, 32, 40, 42, 60], "set": [2, 8, 23, 27, 28, 29, 32, 34, 35, 37, 41, 42, 43, 47, 49, 50, 51, 61], "non": [2, 28, 34, 35, 36, 52, 55, 56, 60], "neg": [2, 15], "valu": [2, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 28, 35, 36, 37, 40, 43, 46, 49, 50, 51, 57, 58, 61], "do": [2, 27, 29, 32, 34, 40, 50, 60], "have": [2, 3, 19, 25, 26, 29, 30, 32, 34, 35, 36, 37, 39, 40, 42, 44, 50], "unexpect": 2, "amount": [2, 37, 41, 60], "traffic": [2, 28], "extra": [2, 9, 15, 16], "caus": [2, 29, 37, 41], "chang": [2, 19, 23, 26, 33, 34, 35, 37, 40, 41, 44, 52, 60], "frequent": 2, "elast": 2, "dynam": 2, "deploy": 2, "model": 2, "secur": 2, "bundl": 2, "follow": [2, 8, 9, 15, 16, 17, 23, 24, 25, 26, 28, 32, 50, 53, 61], "path": [2, 3], "cloudsessionbuild": 2, "config_data": 2, "yaml": 2, "unwrap": [2, 9, 15, 16, 31, 39], "note": [2, 19, 28, 32, 34, 37, 42, 50], "file": [2, 3], "provid": [2, 29, 32, 37, 39, 42, 44, 60, 61], "here": [2, 28, 39, 41, 46, 60], "configur": [2, 23, 27, 28, 30, 32, 56], "datacent": [2, 35, 50], "datacenter1": 2, "certificateauthoritydata": 2, "certificate_data": 2, "server": [2, 42], "9142": [2, 3], "nodedomain": 2, "cql": [2, 8, 19, 32, 35, 43, 48], "id": [2, 57, 58, 59, 61], "com": 2, "insecureskiptlsverifi": 2, "fals": [2, 28, 40, 43], "authinfo": 2, "clientcertificatedata": 2, "clientkeydata": 2, "key_data": 2, "scylladb": [2, 42, 48], "context": 2, "datacenternam": 2, "authinfonam": 2, "currentcontext": 2, "openssl": 3, "crate": [3, 10, 30, 32, 60], "wa": [3, 19, 29, 37, 39, 50, 57, 61], "chosen": 3, "rustl": 3, "certif": 3, "ip": [3, 12], "address": [3, 12, 28], "see": [3, 8, 9, 15, 16, 19, 26, 29, 32, 34, 35, 37, 39, 41, 43, 44, 50, 60], "issu": [3, 32, 36, 44], "common": [3, 23, 29], "case": [3, 9, 15, 16, 25, 28, 29, 32, 36, 37, 40, 41, 50, 52, 60], "pure": 3, "rust": [3, 8, 13, 18, 19, 28, 32, 35, 39, 41, 44, 47], "librari": 3, "instal": [3, 30, 47, 48], "proper": 3, "packag": 3, "add": [3, 34, 45], "cargo": [3, 30, 45], "toml": [3, 45], "version": [3, 27, 32, 33, 40, 45], "4": [3, 5, 6, 8, 16, 21, 32, 34, 45, 57, 58], "ssl": 3, "32": [3, 10], "Then": 3, "debian": 3, "ubuntu": 3, "apt": 3, "libssl": 3, "dev": 3, "pkg": 3, "config": 3, "fedora": 3, "dnf": 3, "devel": 3, "arch": 3, "pacman": 3, "sslcontext": 3, "pass": [3, 29, 34, 37, 41, 44, 60], "ca": 3, "crt": 3, "sslcontextbuild": 3, "sslmethod": 3, "sslverifymod": 3, "pathbuf": 3, "context_build": 3, "set_ca_fil": 3, "set_verifi": 3, "peer": 3, "port": 3, "now": [3, 19, 26, 32, 43, 45, 46, 58, 59], "ssl_context": 3, "full": [3, 9, 16, 30, 45], "more": [3, 8, 9, 15, 16, 19, 32, 34, 35, 36, 37, 39, 40, 41, 42, 44, 50, 52, 60, 61], "detail": [3, 29], "repres": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 32, 39, 41, 60], "intotypedrow": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 36, 39, 41, 46], "insert": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 34, 35, 37, 39, 41, 43, 44, 46, 49, 50, 51, 57, 58], "tabl": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 32, 35, 36, 37, 40, 41, 42, 43, 46, 53, 61], "refer": [5, 28, 29, 32, 44], "move": 5, "whole": [5, 34, 36, 56], "to_insert": [5, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 35, 37, 41, 46, 49, 50, 51], "2": [5, 6, 9, 11, 15, 32, 34, 36, 41, 44, 48, 50], "5": [5, 6, 32, 34], "INTO": [5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 34, 35, 37, 39, 41, 43, 44, 46, 49, 50, 51, 57, 58], "keyspac": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 30, 38, 40, 41, 42, 46, 53], "read": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 38, 41, 46, 50, 60], "from": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 29, 30, 36, 37, 39, 41, 43, 44, 46, 52, 57, 58, 59, 60, 61], "select": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 32, 36, 39, 41, 43, 46, 52, 57, 58, 59, 60], "iter": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 29, 31, 36, 39, 41, 46, 53, 56, 58], "rows_typ": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 39, 41, 46], "while": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 32, 36, 41, 46, 58], "blob_valu": 5, "next": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 36, 41, 46, 50, 58, 60], "transpos": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 41, 46], "println": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 31, 36, 40, 41, 45, 46, 53, 57, 58, 59, 60], "int": [6, 8, 18, 19, 32, 37, 39, 44, 46], "my_list": 6, "i32": [6, 8, 13, 18, 19, 32, 35, 36, 37, 39, 41, 44, 46, 49, 50, 51], "list_valu": 6, "hashset": 6, "btreeset": 6, "my_set": 6, "collect": [6, 8], "into_it": 6, "hashmap": [6, 8, 44], "k": [6, 8, 19, 22, 24, 25, 26, 30, 34, 35, 36, 37, 39, 41, 44, 46, 49, 50, 51, 52, 57, 58, 59, 60], "v": [6, 8], "btreemap": 6, "text": [6, 8, 19, 34, 37, 39, 41, 44], "my_map": 6, "string": [6, 8, 14, 18, 19, 32, 35, 37, 39, 41, 44], "abcd": 6, "16": [6, 18, 34, 36, 37, 44], "map_valu": 6, "pub": [7, 32], "i64": [7, 8, 13, 15, 16], "updat": [7, 27, 29, 34, 40], "frame": [7, 9, 10, 11, 15, 16, 17, 39, 44], "c": [7, 36, 37, 41, 44, 48], "counter_valu": 7, "counter_int_valu": 7, "map": [8, 26, 44], "match": [8, 9, 15, 16, 19, 32, 39, 41, 44], "achiev": [8, 43, 50], "seamless": 8, "send": [8, 29, 32, 34, 36, 41, 43, 44, 60, 61], "receiv": [8, 19, 30, 32, 36, 37, 39, 41, 48, 58], "chapter": [8, 29, 47, 61], "how": [8, 27, 36, 53, 61], "equival": [8, 32], "boolean": 8, "bool": 8, "tinyint": 8, "i8": [8, 13], "smallint": 8, "i16": [8, 13, 32], "bigint": [8, 45], "float": 8, "f32": [8, 13], "doubl": 8, "f64": [8, 13], "ascii": 8, "varchar": 8, "counter": 8, "blob": 8, "inet": 8, "uuid": [8, 17, 45, 57, 58, 59], "timeuuid": 8, "cqltimeuuid": [8, 17], "date": [8, 16], "cqldate": 8, "chrono": 8, "naived": [8, 16], "cqltime": 8, "naivetim": [8, 16], "timestamp": [8, 60], "cqltimestamp": 8, "datetim": 8, "utc": [8, 16, 60], "offsetdatetim": 8, "cqldurat": [8, 11], "decim": 8, "cqldecim": 8, "bigdecim": [8, 45], "varint": 8, "cqlvarint": 8, "num_bigint": 8, "v0": [8, 21], "list": [8, 29, 34, 41, 44, 58, 59, 60], "tupl": [8, 34, 39, 41, 44], "udt": [8, 19, 32], "custom": [8, 17, 19, 29, 37, 41, 42, 44, 52], "macro": [8, 19, 39, 44], "depend": [9, 15, 16, 36, 45], "featur": [9, 10, 15, 16, 21, 45, 61], "flag": [9, 10, 15, 16, 21, 28, 61], "three": [9, 15, 16, 25, 28, 32, 44, 50, 52], "type": [9, 10, 15, 16, 21, 27, 32, 35, 38, 41, 53], "interact": [9, 10, 15, 16, 21], "intern": [9, 15, 16, 29], "number": [9, 10, 15, 16, 21, 27, 31, 32, 34, 39, 50], "dai": [9, 11], "sinc": [9, 15, 16], "5877641": 9, "06": 9, "23": [9, 15], "31": 9, "unix": [9, 16], "epoch": [9, 16], "without": [9, 10, 15, 16, 19, 21, 32, 39, 40, 43, 52, 60], "u32": 9, "wrapper": [9, 10, 15, 16, 17, 21, 32], "represent": [9, 15, 16, 32, 60], "most": [9, 15, 16, 29, 55], "ar": [9, 14, 15, 16, 19, 23, 25, 26, 28, 29, 32, 34, 36, 37, 38, 39, 41, 43, 44, 50, 52, 56, 58, 59, 61], "practic": [9, 15, 16, 32], "section": [9, 15, 16, 32, 37], "1970": [9, 16], "01": [9, 15, 16], "08": [9, 60], "7": [9, 36], "raw": [9, 32, 43], "row": [9, 10, 15, 16, 17, 36, 41, 43, 46, 58], "into_typ": [9, 10, 15, 16, 17, 36], "date_valu": 9, "rang": [9, 16, 28], "262145": 9, "262143": 9, "12": [9, 45], "2021": 9, "03": [9, 15, 21], "24": 9, "from_ymd_opt": [9, 16], "altern": [9, 16], "document": [9, 19, 34, 35, 37, 41, 44, 50], "get": [9, 39, 60, 61], "info": [9, 16, 30, 57, 58, 59], "month": [9, 11, 16], "from_calendar_d": [9, 16], "march": 9, "simpl": [10, 21, 27, 32, 34, 36, 37, 38, 47, 49, 50, 51, 56, 58], "sign": [10, 21], "binari": [10, 21], "big": [10, 21, 36], "endian": [10, 21], "order": [10, 17, 19, 21, 32, 36, 41, 44, 53, 60], "bit": [10, 39], "scale": 10, "fromstr": [10, 21], "123": [10, 13, 16], "456": [10, 15], "from_signed_be_bytes_and_expon": 10, "0x01": 10, "0xe2": 10, "0x40": 10, "decimal_valu": 10, "should": [10, 21, 30, 32, 41, 44, 45, 48], "04": [10, 16, 21], "from_str": [10, 17, 21], "12345": [10, 13, 21, 35, 37, 41, 43, 46, 49, 50, 51], "nanosecond": [11, 15], "duration_valu": 11, "inet_valu": 12, "true": [13, 28, 43, 52, 57, 58, 59], "bool_valu": 13, "tinyint_valu": 13, "smallint_valu": 13, "int_valu": [13, 18, 39], "bigint_valu": 13, "float_valu": 13, "double_valu": 13, "to_insert_str": 14, "abcdef": 14, "text_valu": [14, 39], "midnight": 15, "exce": 15, "86399999999999": 15, "59": 15, "999999999": 15, "64": [15, 16], "1_000_000_000": 15, "time_valu": 15, "although": [15, 27], "leap": 15, "thei": [15, 19, 21, 28, 29, 31, 32, 34, 37, 41, 44], "attempt": [15, 60, 61], "convert": [15, 16, 29, 39, 60], "write": [15, 16, 19, 28, 43, 50], "return": [15, 16, 28, 29, 32, 36, 37, 39, 40, 41, 42, 50, 51, 52, 57], "02": 15, "789": 15, "012": 15, "from_hms_nano_opt": 15, "456_789_012": 15, "from_hms_nano": 15, "describ": [16, 26, 32], "millisecond": [16, 40], "accept": 16, "00": 16, "1000": 16, "timestamp_valu": 16, "timezon": 16, "explicitli": 16, "store": [16, 28], "precis": 16, "finer": 16, "than": [16, 28, 37, 39, 40, 42, 43, 44, 50], "1m": 16, "lost": 16, "naivedatetim": 16, "from_hms_milli_opt": 16, "and_utc": 16, "As": [16, 26, 28, 32, 41, 42], "correct": [16, 28, 32], "eras": 16, "On": [16, 29, 36, 50], "primitivedatetim": 16, "januari": 16, "from_hms_milli": 16, "assume_utc": 16, "logic": [17, 42], "cassandra": [17, 27, 29, 42, 61], "semant": 17, "8e14e760": [17, 20], "7fa8": [17, 20], "11eb": [17, 20], "bc66": [17, 20], "000000000001": [17, 20], "timeuuid_valu": 17, "max": [18, 44], "element": [18, 29, 44], "abc": 18, "tuple_valu": 18, "string_valu": 18, "allow": [19, 23, 28, 29, 32, 34, 36, 38, 43, 60, 61], "name": [19, 32, 39, 43, 44], "field": [19, 28, 32, 39, 44], "offici": 19, "correspond": [19, 50], "sai": [19, 37, 61], "my_typ": 19, "int_val": 19, "text_val": 19, "deriv": [19, 32, 39, 44], "serializecql": 19, "abl": [19, 28, 29, 52, 60], "same": [19, 28, 29, 32, 35, 36, 37, 39, 43, 44, 49, 50, 60, 61], "renam": 19, "attribut": [19, 32, 44], "fromusertyp": [19, 32], "mismatch": 19, "between": [19, 23, 34], "temporari": 19, "situat": [19, 52], "futur": [19, 29, 32, 36, 40, 45, 58], "replac": [19, 32], "earlier": 19, "must": [19, 28, 32, 34, 37, 39, 44], "wrap": [19, 32, 43], "gracefulli": 19, "debug": [19, 51], "mytyp": 19, "import": [19, 35], "deseri": [19, 32], "de": 19, "serial": [19, 23, 24, 33, 35, 36, 41], "anoth": [19, 22, 23, 26, 32, 50, 55, 56, 60], "look": [19, 32], "behaviour": [19, 40, 49, 50], "sent": [19, 29, 32, 34, 37, 41, 44, 60, 61], "just": [19, 30, 32, 34, 35, 36, 37, 43, 44, 52, 60], "like": [19, 34, 35, 36, 37, 48, 60, 61], "cql_to_rust": [19, 39], "fromcqlval": 19, "17": [19, 44, 48], "my_type_valu": 19, "parse_str": 20, "uuid_valu": 20, "num": [21, 45], "accordingli": 21, "varint_valu": 21, "executionprofil": [22, 23, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55], "attach": 22, "statement": [22, 23, 24, 25, 26, 28, 32, 35, 37, 38, 41, 42, 57], "consist": [22, 23, 24, 25, 26, 28, 34, 35, 37, 41, 52, 60], "builder": [22, 24, 25, 26, 28, 29, 42, 49, 50, 51, 54, 55], "localon": 22, "request_timeout": [22, 24, 42], "none": [22, 28, 29, 42, 44], "timeout": [22, 23, 25, 40, 50], "into_handl": [22, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55], "default_execution_profile_handl": [22, 25, 26, 29, 42, 49, 50, 51, 54, 55], "30": [22, 24, 28, 42], "query1": [22, 26], "set_execution_profile_handl": [22, 24, 25, 26, 42, 49, 50, 51], "clone": [22, 25, 26, 36, 60], "query2": [22, 26], "pk": [22, 26, 32], "where": [22, 26, 32, 36, 40, 41, 50, 52, 56], "base": [22, 28, 29, 30, 32, 49, 50, 52], "base_profil": 22, "to_build": 22, "group": [23, 27, 28], "variou": [23, 27, 31, 34], "togeth": [23, 27], "workload": [23, 26, 28], "conveni": [23, 26, 35], "encapsul": 23, "retri": [23, 27, 31, 40, 60, 61], "specul": [23, 29, 61], "There": [23, 28, 56, 61], "two": [23, 25, 26, 29, 32, 34, 35, 39, 43, 48, 50, 61], "class": [23, 30, 46], "relat": 23, "executionprofilehandl": [23, 26], "former": 23, "simpli": [23, 29, 41, 44, 60], "immut": 23, "latter": 23, "particular": [23, 28, 29], "moment": [23, 31], "point": 23, "dure": [23, 31, 32, 56], "lifetim": 23, "assign": [23, 25, 26, 28], "At": 23, "remap": 23, "switch": [23, 26, 27], "characterist": 23, "speculative_execut": [24, 54, 55], "simplespeculativeexecutionpolici": [24, 55], "serialconsist": [24, 35], "load_balanc": [24, 28, 29], "defaultpolici": [24, 29], "retry_polici": [24, 49, 50, 51], "fallthroughretrypolici": [24, 51], "sync": [24, 29, 32, 54, 55, 60], "serial_consist": 24, "load_balancing_polici": [24, 29], "speculative_execution_polici": [24, 54, 55], "max_retry_count": [24, 54, 55], "retry_interv": [24, 55], "from_milli": [24, 55], "100": [24, 55], "profil": [25, 27, 29, 49], "either": [25, 60], "overridden": 25, "upon": [25, 40], "creation": [25, 56], "moreov": 25, "ha": [25, 28, 32, 41, 43, 50, 52, 54, 56, 60, 61], "higher": 25, "directli": [25, 32], "In": [25, 28, 29, 32, 36, 37, 41, 43, 45, 47, 50, 53, 60], "over": [25, 32, 36], "recap": 25, "session_profil": 25, "One": [25, 26, 34, 35, 37, 41, 50], "query_profil": 25, "appli": [25, 28, 32, 52], "therefor": [25, 40, 43, 50], "set_consist": [25, 34, 35, 37, 41], "affect": [26, 28, 32, 36, 41], "been": [26, 40, 50], "quick": [26, 27], "session1": 26, "handle1": 26, "profile1": 26, "statement1": 26, "statement2": 26, "handle2": 26, "profile2": 26, "becom": [26, 28, 35], "yield": [26, 42], "power": 26, "modifi": [26, 34], "your": [26, 29, 36, 44], "below": [26, 32, 42, 50, 53], "abov": [26, 28, 54], "code": [26, 27, 29], "map_to_another_profil": 26, "book": 27, "written": [27, 30, 32], "optim": [27, 29, 56], "compat": [27, 32], "apach": 27, "lesson": 27, "univers": 27, "api": [27, 34, 35, 37, 41], "start": [27, 30, 36, 48, 55, 56, 60], "up": [27, 43, 47, 50], "project": [27, 47], "migrat": [27, 40], "guid": 27, "older": 27, "cluster": [27, 28, 29, 36, 37, 41, 50, 53], "prepar": [27, 28, 29, 36, 38, 41, 49, 50, 51, 52, 58, 61], "batch": [27, 32, 35, 38, 61], "page": [27, 31, 32, 37, 38, 41], "execut": [27, 28, 29, 30, 32, 34, 36, 39, 40, 41, 42, 49, 50, 51, 57], "onc": [27, 32, 34, 38, 53, 60], "column": [27, 32, 39, 44, 53], "what": [27, 43, 60, 61], "fail": [27, 29, 32, 39, 50, 52, 60], "idempot": 27, "metric": [27, 54], "statist": [27, 29], "latenc": [27, 29, 31, 43, 56], "log": [27, 50], "view": [27, 30, 53], "integr": 27, "produc": [27, 32], "trace": [27, 30, 45, 60], "inspect": 27, "local": [28, 35, 42], "mode": 28, "defaultpolicybuild": 28, "rack": 28, "is_token_awar": 28, "permit_dc_failov": 28, "latency_awar": 28, "desir": 28, "default_polici": 28, "prefer_datacenter_and_rack": 28, "dc1": 28, "rack1": 28, "token_awar": 28, "priorit": 28, "locat": 28, "my_dc": 28, "treat": [28, 44], "remot": 28, "zone": 28, "too": 28, "first": [28, 29, 32, 34, 36, 37, 39, 43, 55, 56, 60], "replica": [28, 29, 50], "similarli": 28, "disabl": [28, 29, 32, 40], "includ": [28, 29, 32, 34, 47, 60], "exclud": 28, "even": [28, 34, 50], "aliv": [28, 50], "serv": 28, "event": [28, 57, 58, 59, 60, 61], "outag": 28, "network": 28, "failur": [28, 29, 40, 52], "unavail": [28, 50], "client": [28, 48], "longer": 28, "access": [28, 31, 43, 54, 60], "permit": 28, "due": [28, 34], "constraint": 28, "mechan": [28, 40], "partit": [28, 37], "across": 28, "want": [28, 32, 40, 44], "being": [28, 29, 32, 34, 39, 50], "help": [28, 29, 39, 49], "minim": 28, "improv": 28, "ensur": [28, 32, 39], "much": [28, 32, 37], "within": [28, 35], "assum": 28, "significantli": 28, "scalabl": 28, "built": [28, 32], "reduc": 28, "overhead": [28, 32], "throughput": 28, "pleas": [28, 35, 48], "penalis": 28, "whose": 28, "measur": 28, "recent": 28, "averag": [28, 31], "classifi": 28, "behind": 28, "update_r": 28, "global": [28, 30, 42], "minimum": 28, "comput": [28, 29, 37], "wors": [28, 43], "exclusion_threshold": 28, "retry_period": 28, "involv": 28, "put": [28, 34, 45], "end": [28, 43, 60], "often": 28, "truli": 28, "benefici": 28, "faster": 28, "lag": 28, "worsen": [28, 37, 41], "warn": [28, 30, 34, 36, 37, 41], "NOT": [28, 30, 35, 40, 46], "prior": 28, "benchmark": 28, "prove": 28, "impact": 28, "caution": 28, "latencyawarenessbuild": 28, "latency_awareness_build": 28, "minimum_measur": 28, "200": [28, 40], "further": 28, "customis": 28, "cours": 28, "prefer_datacent": 28, "down": [28, 29, 40], "And": 28, "ones": [28, 32, 61], "prioriti": 28, "shuffl": 28, "randomli": 28, "rotat": 28, "round": [28, 32, 36, 41], "robin": 28, "random": [28, 34, 41], "index": 28, "optimis": 28, "lwt": 28, "ring": 28, "prevent": 28, "content": 28, "paxo": 28, "conflict": 28, "determin": [29, 50], "contact": 29, "gener": [29, 30, 32, 44], "state": [29, 43], "influenc": 29, "open": 29, "blacklist": 29, "host_filt": 29, "hostfilt": 29, "wide": 29, "target": 29, "pair": 29, "construct": 29, "essenti": [29, 32], "best": [29, 32, 34, 36, 43, 50], "might": [29, 32, 36, 37, 39, 40, 41, 44, 48, 49, 52, 60], "better": [29, 37, 38, 44, 50], "suit": 29, "our": [29, 32], "awar": [29, 34, 37, 41], "via": [29, 35], "sampl": [29, 60], "newli": [29, 32], "addit": [29, 32, 35, 36], "through": [29, 32], "level": [29, 35, 50], "basi": 29, "usual": 29, "unnecessari": 29, "entir": 29, "given": [29, 39, 42, 54], "rest": [29, 35], "call": [29, 32, 34, 53, 60], "layer": 29, "filter": [29, 45], "out": [29, 52, 60], "feedback": 29, "health": 29, "decis": [29, 60, 61], "hand": 29, "messag": [29, 30, 48], "overload": 29, "avoid": [29, 39, 43], "again": [29, 32, 40], "until": [29, 42, 60], "recov": 29, "subscrib": [30, 45], "print": [30, 41, 45, 46, 53, 60], "collector": [30, 60], "rust_log": 30, "tracing_subscrib": 30, "fmt": 30, "init": 30, "IF": [30, 35, 46], "exist": [30, 32, 35, 46], "WITH": [30, 46], "replic": [30, 46, 53], "networktopologystrategi": [30, 46], "replication_factor": [30, 46], "folder": 30, "get_metr": 31, "total": 31, "nonpag": 31, "get_queries_num": 31, "get_queries_iter_num": 31, "occur": [31, 53], "get_errors_num": 31, "get_errors_iter_num": 31, "get_latency_avg_m": 31, "99": [31, 54], "9": 31, "percentil": [31, 56], "get_latency_percentile_m": 31, "bind": [32, 34, 44], "marker": [32, 34, 44], "untyp": 32, "form": 32, "safer": 32, "robust": 32, "interfac": 32, "check": [32, 44, 60], "against": [32, 56], "couldn": 32, "kind": 32, "valuelist": [32, 34], "serializedresult": 32, "write_to_request": 32, "buf": 32, "serializevalueserror": 32, "naiv": 32, "hope": [32, 60], "took": 32, "care": [32, 60], "db": 32, "side": [32, 42], "valid": 32, "worst": 32, "reinterpret": 32, "unintend": 32, "manner": 32, "problem": [32, 43], "robustli": 32, "intousertyp": 32, "cumbersom": 32, "deprec": 32, "fix": 32, "previou": [32, 36], "core": 32, "AND": 32, "ck": 32, "associ": 32, "legacybatchvalu": 32, "previous": 32, "batchvalu": [32, 34], "sourc": 32, "were": [32, 61], "notabl": [32, 35], "cach": [32, 34], "come": 32, "did": 32, "correctli": 32, "ergonom": 32, "counterpart": 32, "fromrow": [32, 39], "limit": [32, 40, 42], "properli": [32, 37, 38, 39], "similar": 32, "rework": 32, "plan": 32, "releas": 32, "worth": 32, "keep": 32, "bring": 32, "cannot": [32, 50], "right": 32, "shown": 32, "snippet": 32, "exact": 32, "effect": 32, "complet": [32, 42, 61], "analog": 32, "flavor": [32, 44], "enforce_ord": [32, 44], "skip_name_check": 32, "person": 32, "surnam": 32, "ag": [32, 39], "learn": 32, "consider": 32, "concern": 32, "cachingsess": [32, 37], "alreadi": 32, "explain": 32, "done": [32, 34, 53, 60], "unprepar": [32, 34, 36], "skip": [32, 44, 61], "detect": 32, "noth": [32, 50], "along": [32, 60], "slowdown": 32, "incur": 32, "trip": [32, 36, 41], "uniqu": 32, "roundtrip": [32, 43], "unaccept": 32, "beforehand": 32, "reus": 32, "align": 32, "sensit": 32, "easi": [32, 38], "occurr": [32, 50], "ad": [32, 41, 44], "atribut": 32, "procedur": 32, "larg": [32, 37, 41], "enough": 32, "codebas": 32, "complic": 32, "everyth": [32, 46], "remov": 32, "rather": [32, 40], "util": [32, 61], "newtyp": 32, "valueadapt": 32, "valuelistadapt": 32, "legacybatchvaluesadapt": 32, "zero": 32, "cost": 32, "alloc": 32, "buffer": 32, "rewritten": 32, "shouldn": 32, "effici": 32, "legacybatchvaluesiter": 32, "write_next_to_request": 32, "natur": 32, "safe": 32, "convers": 32, "direct": [32, 42], "respect": 32, "impl_serialize_cql_via_valu": 32, "impl_serialize_row_via_value_list": 32, "11": [33, 60], "These": 34, "delet": [34, 44], "prepared_stat": [34, 36, 37, 49, 50, 51, 52, 57, 58, 59], "preparedstat": [34, 35, 36, 37, 49, 50, 51, 52, 57, 58, 59], "append_stat": [34, 57], "tab": [34, 35, 37, 39, 41, 43, 44, 49, 50, 51, 52, 57, 58, 59], "b": [34, 36, 37, 39, 41, 43, 44], "manual": [34, 35, 41, 49, 50, 51, 52, 57, 58, 61], "6": [34, 36, 45], "bound": [34, 37, 41, 44], "batch_valu": 34, "5_i32": 34, "sequenti": [34, 60], "consid": 34, "instead": [34, 36, 37, 41, 43], "individu": 34, "simple_unprepared1": 34, "simple_unprepared2": 34, "prepared_batch": 34, "prepare_batch": 34, "1_i32": [34, 44], "2_i32": [34, 41, 44], "3_i32": 34, "4_i32": 34, "length": 34, "equal": 34, "trait": [34, 44, 52], "slice": [34, 44], "unit": [34, 44], "third": [34, 60], "express": 35, "serial_consistency_level": 35, "separ": [35, 61], "simplequeri": 35, "lai": 35, "condit": 35, "rememb": 35, "localseri": 35, "variant": [35, 36], "commonli": 35, "cross": 35, "overrid": 35, "ONE": [35, 41], "my_queri": [35, 41, 49, 50, 51, 52], "set_serial_consist": 35, "remain": 35, "ident": 35, "sometim": [36, 40, 50], "fit": [36, 38], "query_it": [36, 61], "execute_it": [36, 61], "fulli": [36, 38], "amort": 36, "stream": [36, 60], "streamext": [36, 58], "rows_stream": 36, "next_row_r": 36, "set_page_s": 36, "extract": 36, "That": 36, "left": 36, "off": [36, 42], "paged_queri": 36, "with_page_s": 36, "res1": 36, "res2": 36, "query_pag": 36, "paging_st": 36, "paged_prepar": 36, "execute_pag": 36, "later": 37, "work": [37, 41], "kei": [37, 46, 53], "don": [37, 39, 41, 43], "unpag": [37, 41], "heavi": [37, 41], "size": [37, 41], "least": [37, 50], "succe": [37, 50, 60], "inherit": 37, "especi": 37, "good": 37, "otherwis": [37, 40, 50], "hash": 37, "wrong": 37, "prepare_t": 37, "primari": [37, 46, 53], "wrong_prepar": 37, "54321": [37, 43], "matter": [37, 41, 60], "good_prepar": 37, "poor": 38, "primit": 38, "fast": 38, "addition": [38, 41], "special": 38, "asynchron": 38, "wish": [38, 40, 42], "queryresult": [39, 41, 57], "awkward": 39, "as_ref": [39, 44], "as_int": 39, "rowt": 39, "maybe_first_row_typ": 39, "first_row_typ": 39, "maybe_first_row": 39, "single_row_typ": 39, "first_row": 39, "result_not_row": 39, "bug": [39, 40], "first_int_v": 39, "no_row": 39, "str_or_nul": 39, "myrow": 39, "my_row": 39, "agre": 40, "automat": 40, "alter": 40, "wait": [40, 60], "never": [40, 41, 44, 51, 52], "slow": 40, "somebodi": 40, "sens": 40, "said": 40, "auto_await_schema_agr": 40, "await_schema_agr": 40, "ed": 40, "long": 40, "won": 40, "forev": 40, "sessionconfig": 40, "elaps": 40, "queryerror": [40, 42], "requesttimeout": [40, 42], "schema_vers": 40, "sleep": 40, "schema_agreement_interv": 40, "check_schema_agr": 40, "is_som": 40, "els": 40, "IN": 40, "anyth": [41, 61], "Into": 41, "constant": [41, 44, 55], "variabl": [41, 44], "fill": [41, 44], "easiest": [41, 48, 55], "integ": [41, 44], "text2": 41, "could": [41, 42, 43, 44], "lead": [41, 44], "sql": [41, 44], "inject": [41, 44], "pars": 41, "read_row": [41, 46], "place": 41, "With": 41, "immedi": 42, "continu": [42, 60], "still": [42, 43, 50, 60], "progress": 42, "interrupt": 42, "current": [42, 50, 54, 56], "turn": 42, "no_timeout_profile_handl": 42, "block": 42, "indefinit": 42, "hang": 42, "truncat": 42, "three_sec_timeout_profile_handl": 42, "last": 42, "arriv": 42, "omit": 43, "cqlsh": 43, "my_keyspac": 43, "easili": 43, "other_keyspac": 43, "other_t": 43, "use_keyspac": 43, "test1": 43, "test2": 43, "argument": 43, "whether": 43, "slightli": 43, "half": 43, "insensit": 43, "altogeth": 43, "happen": [43, 50, 61], "lowercas": 43, "uppercas": 43, "serializerow": 44, "sort": 44, "intstr": 44, "int_str": 44, "42_i32": 44, "hello": [44, 45], "to_own": 44, "intstringcustom": 44, "first_valu": 44, "second_valu": 44, "int_string_custom": 44, "trail": 44, "coma": 44, "syntax": 44, "val": 44, "cqlvalu": 44, "avalu": 44, "bvalu": 44, "null_i32": 44, "tombston": 44, "maybeunset": 44, "suboptim": 44, "enum": 44, "unset_i32": 44, "sure": [44, 50], "instruct": 44, "myproject": 45, "13": 45, "36": 45, "14": 45, "r": 45, "readi": [46, 48], "small": 46, "extab": 46, "topic": 47, "docker": 47, "imag": 48, "linux": 48, "sudo": 48, "rm": 48, "p": 48, "smp": 48, "download": 48, "minut": 48, "listen": 48, "172": 48, "stop": 48, "press": 48, "ctrl": 48, "found": 48, "dockerhub": 48, "high": [49, 52], "chanc": [49, 50, 52], "datastax": [49, 50], "java": [49, 50], "defaultretrypolici": [49, 50], "set_retry_polici": 49, "lower": [50, 52], "bewar": 50, "break": 50, "guarante": 50, "word": 50, "quorum": 50, "preced": 50, "understood": 50, "highli": 50, "But": 50, "top": 50, "respond": [50, 60], "greater": 50, "writetyp": 50, "unloggedbatch": 50, "acknowledg": 50, "furthermor": 50, "ignor": 50, "except": 50, "rule": 50, "eachquorum": 50, "reach": 50, "overal": 50, "assumpt": 50, "host": [50, 54], "coordin": 50, "know": 50, "thu": 50, "silent": 50, "persist": 50, "idea": 50, "thing": 50, "someth": 50, "risk": 50, "stale": 50, "downgrading_consistency_retry_polici": 50, "downgradingconsistencyretrypolici": 50, "falthroughretrypolici": 51, "straight": [51, 52], "decid": [52, 60], "fallthrough": 52, "downgrad": 52, "behav": 52, "retrypolici": 52, "retrysess": 52, "increas": 52, "danger": 52, "figur": 52, "set_is_idempot": 52, "present": 53, "demand": 53, "newest": 53, "refresh_metadata": 53, "metadata": 53, "snapshot": 53, "examin": 53, "obtain": [53, 61], "belong": 53, "materi": 53, "strategi": [53, 56], "definit": 53, "partition": 53, "show": 53, "cluster_data": 53, "get_cluster_data": 53, "get_keyspace_info": 53, "keyspace_nam": 53, "keyspace_info": 53, "ttabl": 53, "tview": 53, "tudt": 53, "user_defined_typ": 53, "trigger": 54, "percentilespeculativeexecutionpolici": 54, "execution_profil": [54, 55], "delai": 55, "count": 55, "techniqu": 56, "pre": 56, "emptiv": 56, "repli": 56, "tracing_id": [57, 58, 59, 61], "tracinginfo": [57, 58, 59, 61], "set_trac": [57, 58, 59], "re": 57, "system_trac": [57, 58, 59, 61], "tracing_info": [57, 58, 59], "get_tracing_info": [57, 58, 59, 61], "subsequ": 58, "rowiter": 58, "row_iter": 58, "_row": 58, "get_tracing_id": 58, "prepare_tracing_id": 59, "to_prepar": 59, "fiber": 60, "historycollector": 60, "history_listen": 60, "set_history_listen": 60, "save": 60, "_ignore_error": 60, "structured_histori": 60, "clone_structured_histori": 60, "didn": 60, "encount": 60, "difficulti": 60, "start_tim": 60, "2022": 60, "25": 60, "21": 60, "50": 60, "445075147": 60, "445151628": 60, "447444362": 60, "447447970": 60, "had": 60, "troubl": 60, "26": 60, "15": 60, "28": 60, "525367409": 60, "219": 60, "525409294": 60, "yet": 60, "537074167": 60, "217": 60, "537126083": 60, "548050242": 60, "218": 60, "548089083": 60, "590052778": 60, "590078119": 60, "understand": 60, "answer": 60, "consult": 60, "made": [60, 61], "tri": 60, "quicker": 60, "spawn": 60, "wasn": 60, "acquir": 60, "analyz": 60, "structur": 60, "monitor": 61, "signifi": 61, "went": 61, "go": 61, "insid": 61, "think": 61}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"authent": 0, "import": 0, "The": 0, "default": [0, 32, 49], "credenti": 0, "ar": 0, "sent": 0, "plain": 0, "text": [0, 14], "server": 0, "For": 0, "thi": 0, "reason": 0, "i": [0, 32, 40], "highli": 0, "recommend": 0, "us": [0, 2, 3, 39, 43, 48], "conjunct": 0, "client": 0, "node": [0, 28], "encrypt": 0, "ssl": 0, "trust": 0, "network": 0, "environ": 0, "custom": [0, 32, 39, 60], "compress": 1, "connect": [2, 46], "cluster": 2, "best": 2, "practic": 2, "session": [2, 37, 58, 59], "metadata": 2, "scylla": [2, 27, 48], "cloud": 2, "serverless": 2, "tl": 3, "enabl": 3, "featur": 3, "blob": 5, "list": [6, 32], "set": [6, 22, 25], "map": 6, "counter": 7, "data": [8, 39, 44], "type": [8, 19, 39, 44], "date": 9, "cqldate": 9, "chrono": [9, 15, 16], "naived": 9, "time": [9, 15, 16], "decim": 10, "valu": [10, 21, 32, 34, 39, 41, 44], "cqldecim": 10, "bigdecim": 10, "durat": 11, "inet": 12, "bool": 13, "tinyint": 13, "smallint": 13, "int": 13, "bigint": [13, 21], "float": 13, "doubl": 13, "ascii": 14, "varchar": 14, "cqltime": 15, "naivetim": 15, "timestamp": 16, "cqltimestamp": 16, "datetim": 16, "offsetdatetim": 16, "timeuuid": 17, "tupl": 18, "user": 19, "defin": 19, "uuid": 20, "varint": 21, "num_bigint": 21, "cqlvarint": 21, "exampl": [21, 22, 24, 25, 26, 31, 36, 49, 50, 51, 54, 55, 60], "creat": [22, 28, 45], "profil": [22, 23, 24, 26], "execut": [23, 25, 26, 37, 54, 55, 56, 60, 61], "all": 24, "option": [24, 34, 37], "support": 24, "prioriti": 25, "remap": 26, "handl": 26, "rust": 27, "driver": [27, 31, 60], "other": [27, 39, 44], "document": 27, "content": 27, "defaultpolici": 28, "semant": 28, "prefer": 28, "datacent": 28, "failov": 28, "token": 28, "awar": 28, "latenc": 28, "order": 28, "produc": 28, "plan": [28, 29], "load": 29, "balanc": 29, "introduct": 29, "polici": [29, 49, 50, 51, 52], "configur": [29, 36, 52], "loadbalancingpolici": 29, "trait": [29, 32, 60], "pick": 29, "fallback": 29, "on_query_success": 29, "on_query_failur": 29, "log": 30, "metric": 31, "collect": [31, 60], "adjust": 32, "code": [32, 60], "chang": 32, "serial": 32, "api": 32, "introduc": 32, "0": 32, "11": 32, "background": 32, "old": 32, "v": 32, "new": 32, "migrat": [32, 33], "scenario": 32, "differ": 32, "behavior": 32, "serializerow": 32, "serializecql": 32, "macro": 32, "prepar": [32, 34, 37, 57, 59], "mandatori": 32, "non": 32, "empti": 32, "from": 32, "gradual": 32, "convert": 32, "an": 32, "object": 32, "implement": 32, "guid": 33, "batch": [34, 57], "statement": 34, "perform": [34, 36, 37, 41], "lightweight": 35, "transact": 35, "lwt": 35, "queri": [35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 52, 57, 58, 60, 61], "format": 35, "page": [36, 58], "size": 36, "pass": 36, "state": 36, "manual": [36, 40], "make": 38, "result": [39, 41], "basic": 39, "represent": 39, "pars": 39, "into_typ": 39, "conveni": 39, "method": 39, "null": [39, 44], "row": 39, "struct": 39, "schema": [40, 53], "agreement": 40, "autom": 40, "await": 40, "interv": 40, "check": 40, "now": 40, "simpl": [41, 46, 55, 57], "first": 41, "argument": 41, "second": 41, "timeout": 42, "keyspac": 43, "multipl": 43, "onc": 43, "case": 43, "sensit": 43, "unset": 44, "project": 45, "run": [46, 48], "quick": 47, "start": 47, "docker": 48, "more": 48, "inform": 48, "retri": [49, 50, 51, 52], "downgrad": 50, "consist": 50, "fallthrough": 51, "idempot": 52, "fetch": 53, "inspect": 53, "percentil": 54, "specul": [54, 55, 56, 60], "trace": [57, 58, 59, 61], "query_it": 58, "execute_it": 58, "histori": [60, 61], "output": 60, "how": 60, "No": 60, "structuredhistori": 60, "historylisten": 60}, "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": {"Inet": [[12, "inet"]], "Timestamp": [[16, "timestamp"]], "CqlTimestamp": [[16, "cqltimestamp"]], "chrono::DateTime": [[16, "chrono-datetime"]], "time::OffsetDateTime": [[16, "time-offsetdatetime"]], "Varint": [[21, "varint"]], "num_bigint::BigInt": [[21, "num-bigint-bigint"]], "value::CqlVarint": [[21, "value-cqlvarint"]], "Example": [[21, "example"], [22, "example"], [22, "id1"], [22, "id2"], [25, "example"], [26, "example"], [31, "example"], [24, "example"], [55, "example"], [54, "example"]], "Uuid": [[20, "uuid"]], "User defined types": [[19, "user-defined-types"]], "Time": [[15, "time"]], "CqlTime": [[15, "cqltime"]], "chrono::NaiveTime": [[15, "chrono-naivetime"]], "time::Time": [[15, "time-time"]], "Timeuuid": [[17, "timeuuid"]], "Execution profiles": [[23, "execution-profiles"]], "Ascii, Text, Varchar": [[14, "ascii-text-varchar"]], "Tuple": [[18, "tuple"]], "Creating a profile and setting it": [[22, "creating-a-profile-and-setting-it"]], "Bool, Tinyint, Smallint, Int, Bigint, Float, Double": [[13, "bool-tinyint-smallint-int-bigint-float-double"]], "Bool": [[13, "bool"]], "Tinyint": [[13, "tinyint"]], "Smallint": [[13, "smallint"]], "Int": [[13, "int"]], "Bigint": [[13, "bigint"]], "Float": [[13, "float"]], "Double": [[13, "double"]], "Authentication": [[0, "authentication"]], "Important: The default authentication credentials are sent in plain text to the server. For this reason, it is highly recommended that this be used in conjunction with client-to-node encryption (SSL), or in a trusted network environment.": [[0, "important-the-default-authentication-credentials-are-sent-in-plain-text-to-the-server-for-this-reason-it-is-highly-recommended-that-this-be-used-in-conjunction-with-client-to-node-encryption-ssl-or-in-a-trusted-network-environment"]], "Custom Authentication": [[0, "custom-authentication"]], "List, Set, Map": [[6, "list-set-map"]], "List": [[6, "list"]], "Set": [[6, "set"]], "Map": [[6, "map"]], "Blob": [[5, "blob"]], "Date": [[9, "date"]], "CqlDate": [[9, "cqldate"]], "chrono::NaiveDate": [[9, "chrono-naivedate"]], "time::Date": [[9, "time-date"]], "Decimal": [[10, "decimal"]], "value::CqlDecimal": [[10, "value-cqldecimal"]], "bigdecimal::BigDecimal": [[10, "bigdecimal-bigdecimal"]], "Connecting to the cluster": [[2, "connecting-to-the-cluster"]], "Best practices for using Session": [[2, "best-practices-for-using-session"]], "Metadata": [[2, "metadata"]], "Scylla Cloud Serverless": [[2, "scylla-cloud-serverless"]], "TLS": [[3, "tls"]], "Enabling feature": [[3, "enabling-feature"]], "Using TLS": [[3, "using-tls"]], "Compression": [[1, "compression"]], "Counter": [[7, "counter"]], "Data Types": [[8, "data-types"]], "Duration": [[11, "duration"]], "USE keyspace": [[43, "use-keyspace"]], "Multiple use queries at once": [[43, "multiple-use-queries-at-once"]], "Case sensitivity": [[43, "case-sensitivity"]], "Paged query": [[36, "paged-query"]], "Examples": [[36, "examples"], [49, "examples"], [50, "examples"], [51, "examples"]], "Configuring page size": [[36, "configuring-page-size"]], "Passing the paging state manually": [[36, "passing-the-paging-state-manually"]], "Performance": [[36, "performance"], [37, "performance"], [41, "performance"], [34, "performance"]], "Prepared query": [[37, "prepared-query"]], "Session::prepare": [[37, "session-prepare"]], "Session::execute": [[37, "session-execute"]], "Query options": [[37, "query-options"]], "Query values": [[44, "query-values"]], "NULL values": [[44, "null-values"], [39, "null-values"]], "Unset values": [[44, "unset-values"]], "Other data types": [[44, "other-data-types"], [39, "other-data-types"]], "Connecting and running a simple query": [[46, "connecting-and-running-a-simple-query"]], "Query timeouts": [[42, "query-timeouts"]], "Schema agreement": [[40, "schema-agreement"]], "Automated awaiting schema agreement": [[40, "automated-awaiting-schema-agreement"]], "Manually awaiting schema agreement": [[40, "manually-awaiting-schema-agreement"]], "Interval of checking for schema agreement": [[40, "interval-of-checking-for-schema-agreement"]], "Checking if schema is in agreement now": [[40, "checking-if-schema-is-in-agreement-now"]], "Query result": [[39, "query-result"], [41, "query-result"]], "Basic representation": [[39, "basic-representation"]], "Parsing using into_typed": [[39, "parsing-using-into-typed"]], "Parsing using convenience methods": [[39, "parsing-using-convenience-methods"]], "Parsing row as a custom struct": [[39, "parsing-row-as-a-custom-struct"]], "Making queries": [[38, "making-queries"]], "Creating a project": [[45, "creating-a-project"]], "Quick Start": [[47, "quick-start"]], "Simple query": [[41, "simple-query"]], "First argument - the query": [[41, "first-argument-the-query"]], "Second argument - the values": [[41, "second-argument-the-values"]], "Priorities of execution settings": [[25, "priorities-of-execution-settings"]], "Batch statement": [[34, "batch-statement"]], "Preparing a batch": [[34, "preparing-a-batch"]], "Batch options": [[34, "batch-options"]], "Batch values": [[34, "batch-values"]], "DefaultPolicy": [[28, "defaultpolicy"]], "Creating a DefaultPolicy": [[28, "creating-a-defaultpolicy"]], "Semantics of DefaultPolicy": [[28, "semantics-of-defaultpolicy"]], "Preferences": [[28, "preferences"]], "Datacenter Failover": [[28, "datacenter-failover"]], "Token awareness": [[28, "token-awareness"]], "Latency awareness": [[28, "latency-awareness"]], "Creating a latency aware DefaultPolicy": [[28, "creating-a-latency-aware-defaultpolicy"]], "Node order in produced plans": [[28, "node-order-in-produced-plans"]], "Adjusting code to changes in serialization API introduced in 0.11": [[32, "adjusting-code-to-changes-in-serialization-api-introduced-in-0-11"]], "Background": [[32, "background"]], "Old vs. new": [[32, "old-vs-new"]], "Migration scenarios": [[32, "migration-scenarios"]], "Different default behavior in SerializeRow/SerializeCql macros": [[32, "different-default-behavior-in-serializerow-serializecql-macros"]], "Preparing is mandatory with a non-empty list of values": [[32, "preparing-is-mandatory-with-a-non-empty-list-of-values"]], "Migrating from old to new traits gradually": [[32, "migrating-from-old-to-new-traits-gradually"]], "Converting an object implementing an old trait to a new trait": [[32, "converting-an-object-implementing-an-old-trait-to-a-new-trait"]], "Custom implementations of old traits": [[32, "custom-implementations-of-old-traits"]], "Lightweight transaction (LWT) query": [[35, "lightweight-transaction-lwt-query"]], "Format of the query": [[35, "format-of-the-query"]], "Remapping execution profile handles": [[26, "remapping-execution-profile-handles"]], "Load balancing": [[29, "load-balancing"]], "Introduction": [[29, "introduction"]], "Plan": [[29, "plan"]], "Policy": [[29, "policy"]], "Configuration": [[29, "configuration"]], "LoadBalancingPolicy trait": [[29, "loadbalancingpolicy-trait"]], "pick and fallback:": [[29, "pick-and-fallback"]], "on_query_success and on_query_failure:": [[29, "on-query-success-and-on-query-failure"]], "Logging": [[30, "logging"]], "Driver metrics": [[31, "driver-metrics"]], "Collected metrics:": [[31, "collected-metrics"]], "Scylla Rust Driver": [[27, "scylla-rust-driver"]], "Other documentation": [[27, "other-documentation"]], "Contents": [[27, "contents"]], "Migration guides": [[33, "migration-guides"]], "All options supported by a profile": [[24, "all-options-supported-by-a-profile"]], "Query tracing": [[61, "query-tracing"]], "Tracing": [[61, "tracing"]], "Query Execution History": [[61, "query-execution-history"], [60, "query-execution-history"]], "Example code": [[60, "example-code"]], "Output": [[60, "output"]], "How the driver executes queries": [[60, "how-the-driver-executes-queries"]], "No speculative execution": [[60, "no-speculative-execution"]], "Speculative execution": [[60, "speculative-execution"], [56, "speculative-execution"]], "StructuredHistory": [[60, "structuredhistory"]], "HistoryListener trait, custom history collecting": [[60, "historylistener-trait-custom-history-collecting"]], "Default retry policy": [[49, "default-retry-policy"]], "Retry policy configuration": [[52, "retry-policy-configuration"]], "Retry policies": [[52, "retry-policies"]], "Query idempotence": [[52, "query-idempotence"]], "Schema": [[53, "schema"]], "Fetching schema": [[53, "fetching-schema"]], "Inspecting schema": [[53, "inspecting-schema"]], "Tracing Session::prepare": [[59, "tracing-session-prepare"]], "Simple speculative execution": [[55, "simple-speculative-execution"]], "Running Scylla using Docker": [[48, "running-scylla-using-docker"]], "Running scylla": [[48, "running-scylla"]], "More information": [[48, "more-information"]], "Downgrading consistency retry policy": [[50, "downgrading-consistency-retry-policy"]], "Tracing a paged query": [[58, "tracing-a-paged-query"]], "Tracing Session::query_iter": [[58, "tracing-session-query-iter"]], "Tracing Session::execute_iter": [[58, "tracing-session-execute-iter"]], "Tracing a simple/prepared/batch query": [[57, "tracing-a-simple-prepared-batch-query"]], "Tracing a simple query": [[57, "tracing-a-simple-query"]], "Tracing a prepared query": [[57, "tracing-a-prepared-query"]], "Tracing a batch query": [[57, "tracing-a-batch-query"]], "Percentile speculative execution": [[54, "percentile-speculative-execution"]], "Fallthrough retry policy": [[51, "fallthrough-retry-policy"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/stable/sitemap.xml b/stable/sitemap.xml new file mode 100644 index 0000000000..3389fbb0c3 --- /dev/null +++ b/stable/sitemap.xml @@ -0,0 +1,2 @@ + +https://rust-driver.docs.scylladb.com/stable/connecting/authentication.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/compression.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/connecting.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/tls.htmlhttps://rust-driver.docs.scylladb.com/stable/contents.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/time.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/blob.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/timestamp.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/timeuuid.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/collections.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/tuple.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/counter.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/udt.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/uuid.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/data-types.htmlhttps://rust-driver.docs.scylladb.com/stable/load-balancing/load-balancing.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/varint.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/date.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/create-and-use.htmlhttps://rust-driver.docs.scylladb.com/stable/logging/logging.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/decimal.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/execution-profiles.htmlhttps://rust-driver.docs.scylladb.com/stable/metrics/metrics.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/duration.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/maximal-example.htmlhttps://rust-driver.docs.scylladb.com/stable/migration-guides/0.11-serialization.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/inet.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/priority.htmlhttps://rust-driver.docs.scylladb.com/stable/migration-guides/migration-guides.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/primitive.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/remap.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/text.htmlhttps://rust-driver.docs.scylladb.com/stable/index.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/basic.htmlhttps://rust-driver.docs.scylladb.com/stable/load-balancing/default-policy.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/batch.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/paged.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/prepare.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/lwt.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/query-history.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/paged.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/usekeyspace.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/prepared.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/queries.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/values.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/tracing.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/result.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/create-project.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/schema-agreement.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/simple.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/timeouts.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/example.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/quickstart.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/scylla-docker.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/default.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/downgrading-consistency.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/fallthrough.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/retry-policy.htmlhttps://rust-driver.docs.scylladb.com/stable/schema/schema.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/percentile.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/simple.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/speculative.htmlhttps://rust-driver.docs.scylladb.com/stable/genindex.htmlhttps://rust-driver.docs.scylladb.com/stable/404.htmlhttps://rust-driver.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/stable/speculative-execution/percentile.html b/stable/speculative-execution/percentile.html new file mode 100644 index 0000000000..74e139d5a7 --- /dev/null +++ b/stable/speculative-execution/percentile.html @@ -0,0 +1,653 @@ + + + + + + + + + + + + + Percentile speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Percentile speculative execution

        +

        This policy has access to Metrics shared with session, and triggers +speculative execution when the request to the current host is above a +given percentile.

        +
        +

        Example

        +

        To use this policy in Session:

        +
        use std::{sync::Arc, time::Duration};
        +use scylla::{
        +    Session,
        +    SessionBuilder,
        +    speculative_execution::PercentileSpeculativeExecutionPolicy,
        +    transport::execution_profile::ExecutionProfile,
        +};
        +
        +let policy = PercentileSpeculativeExecutionPolicy  {
        +    max_retry_count: 3,
        +    percentile: 99.0,
        +};
        +
        +let handle = ExecutionProfile::builder()
        +    .speculative_execution_policy(Some(Arc::new(policy)))
        +    .build()
        +    .into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .default_execution_profile_handle(handle)
        +    .build()
        +    .await?;
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/speculative-execution/simple.html b/stable/speculative-execution/simple.html new file mode 100644 index 0000000000..140153373b --- /dev/null +++ b/stable/speculative-execution/simple.html @@ -0,0 +1,654 @@ + + + + + + + + + + + + + Simple speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Simple speculative execution

        +

        The easiest speculative execution policy available. It starts another +execution of a query after constant delay of retry_interval and does at most +max_retry_count speculative query executions (not counting the first, +non-speculative one).

        +
        +

        Example

        +

        To use this policy in Session:

        +
        use std::{sync::Arc, time::Duration};
        +use scylla::{
        +    Session,
        +    SessionBuilder,
        +    speculative_execution::SimpleSpeculativeExecutionPolicy,
        +    transport::execution_profile::ExecutionProfile,
        +};
        +
        +let policy = SimpleSpeculativeExecutionPolicy {
        +    max_retry_count: 3,
        +    retry_interval: Duration::from_millis(100),
        +};
        +
        +let handle = ExecutionProfile::builder()
        +    .speculative_execution_policy(Some(Arc::new(policy)))
        +    .build()
        +    .into_handle();
        +
        +let session: Session = SessionBuilder::new()
        +    .known_node("127.0.0.1:9042")
        +    .default_execution_profile_handle(handle)
        +    .build()
        +    .await?;
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/speculative-execution/speculative.html b/stable/speculative-execution/speculative.html new file mode 100644 index 0000000000..c43e491485 --- /dev/null +++ b/stable/speculative-execution/speculative.html @@ -0,0 +1,619 @@ + + + + + + + + + + + + + Speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Speculative execution

        +

        Speculative query execution is an optimization technique where a driver +pre-emptively starts a second execution of a query against another node, +before the first node has replied.

        +

        There are multiple speculative execution strategies that the driver can use. +Speculative execution can be configured for the whole whole Session during +its creation.

        +

        Available speculative execution strategies:

        + +

        Speculative execution is not enabled by default, and currently only +non-iter session methods use it.

        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/tracing/basic.html b/stable/tracing/basic.html new file mode 100644 index 0000000000..77a30edee2 --- /dev/null +++ b/stable/tracing/basic.html @@ -0,0 +1,698 @@ + + + + + + + + + + + + + Tracing a simple/prepared/batch query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Tracing a simple/prepared/batch query

        +

        Simple query, prepared query and batch query +return a QueryResult which contains a tracing_id if tracing was enabled.

        +
        +

        Tracing a simple query

        +
        use scylla::query::Query;
        +use scylla::QueryResult;
        +use scylla::tracing::TracingInfo;
        +use uuid::Uuid;
        +
        +// Create a Query manually and enable tracing
        +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)");
        +query.set_tracing(true);
        +
        +let res: QueryResult = session.query(query, &[]).await?;
        +let tracing_id: Option<Uuid> = res.tracing_id;
        +
        +if let Some(id) = tracing_id {
        +    // Query tracing info from system_traces.sessions and system_traces.events
        +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
        +    println!("tracing_info: {:#?}", tracing_info);
        +}
        +
        +
        +
        +
        +

        Tracing a prepared query

        +
        use scylla::prepared_statement::PreparedStatement;
        +use scylla::QueryResult;
        +use scylla::tracing::TracingInfo;
        +use uuid::Uuid;
        +
        +// Prepare the query
        +let mut prepared: PreparedStatement = session
        +    .prepare("SELECT a FROM ks.tab")
        +    .await?;
        +
        +// Enable tracing for the prepared query
        +prepared.set_tracing(true);
        +
        +let res: QueryResult = session.execute(&prepared, &[]).await?;
        +let tracing_id: Option<Uuid> = res.tracing_id;
        +
        +if let Some(id) = tracing_id {
        +    // Query tracing info from system_traces.sessions and system_traces.events
        +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
        +    println!("tracing_info: {:#?}", tracing_info);
        +}
        +
        +
        +
        +
        +

        Tracing a batch query

        +
        use scylla::batch::Batch;
        +use scylla::QueryResult;
        +use scylla::tracing::TracingInfo;
        +use uuid::Uuid;
        +
        +// Create a batch statement
        +let mut batch: Batch = Default::default();
        +batch.append_statement("INSERT INTO ks.tab (a) VALUES(4)");
        +
        +// Enable tracing
        +batch.set_tracing(true);
        +
        +let res: QueryResult = session.batch(&batch, ((),)).await?;
        +let tracing_id: Option<Uuid> = res.tracing_id;
        +
        +if let Some(id) = tracing_id {
        +    // Query tracing info from system_traces.sessions and system_traces.events
        +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
        +    println!("tracing_info: {:#?}", tracing_info);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/tracing/paged.html b/stable/tracing/paged.html new file mode 100644 index 0000000000..e1bc7cc483 --- /dev/null +++ b/stable/tracing/paged.html @@ -0,0 +1,686 @@ + + + + + + + + + + + + + Tracing a paged query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Tracing a paged query

        +

        A paged query performs multiple simple/prepared queries to query subsequent pages.
        +If tracing is enabled the row iterator will contain a list of tracing ids for all performed queries.

        +
        +

        Tracing Session::query_iter

        +
        use scylla::query::Query;
        +use scylla::transport::iterator::RowIterator;
        +use scylla::tracing::TracingInfo;
        +use futures::StreamExt;
        +use uuid::Uuid;
        +
        +// Create a Query manually and enable tracing
        +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)");
        +query.set_tracing(true);
        +
        +// Create a paged query iterator and fetch pages
        +let mut row_iterator: RowIterator = session.query_iter(query, &[]).await?;
        +while let Some(_row) = row_iterator.next().await {
        +    // Receive rows
        +}
        +
        +// Now there are tracing ids for each performed query
        +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids();
        +
        +for id in tracing_ids {
        +    // Query tracing info from system_traces.sessions and system_traces.events
        +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
        +    println!("tracing_info: {:#?}", tracing_info);
        +}
        +
        +
        +
        +
        +

        Tracing Session::execute_iter

        +
        use scylla::prepared_statement::PreparedStatement;
        +use scylla::transport::iterator::RowIterator;
        +use scylla::tracing::TracingInfo;
        +use futures::StreamExt;
        +use uuid::Uuid;
        +
        +// Prepare the query
        +let mut prepared: PreparedStatement = session
        +    .prepare("SELECT a FROM ks.tab")
        +    .await?;
        +
        +// Enable tracing for the prepared query
        +prepared.set_tracing(true);
        +
        +// Create a paged query iterator and fetch pages
        +let mut row_iterator: RowIterator = session.execute_iter(prepared, &[]).await?;
        +while let Some(_row) = row_iterator.next().await {
        +    // Receive rows
        +}
        +
        +// Now there are tracing ids for each performed query
        +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids();
        +
        +for id in tracing_ids {
        +    // Query tracing info from system_traces.sessions and system_traces.events
        +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
        +    println!("tracing_info: {:#?}", tracing_info);
        +}
        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/tracing/prepare.html b/stable/tracing/prepare.html new file mode 100644 index 0000000000..23c0637b96 --- /dev/null +++ b/stable/tracing/prepare.html @@ -0,0 +1,634 @@ + + + + + + + + + + + + + Tracing Session::prepare | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Tracing Session::prepare

        +

        Session::prepare prepares a query on all connections. If tracing is enabled for the Query to prepare, the resulting PreparedStatement will contain prepare_tracing_ids. prepare_tracing_ids is a list of tracing ids of prepare requests on all connections.

        +
        use scylla::query::Query;
        +use scylla::prepared_statement::PreparedStatement;
        +use scylla::tracing::TracingInfo;
        +use uuid::Uuid;
        +
        +// Prepare the query with tracing enabled
        +let mut to_prepare: Query = Query::new("SELECT a FROM ks.tab");
        +to_prepare.set_tracing(true);
        +
        +let mut prepared: PreparedStatement = session
        +    .prepare(to_prepare)
        +    .await?;
        +
        +// Now there are tracing ids for each prepare request
        +let tracing_ids: &[Uuid] = &prepared.prepare_tracing_ids;
        +
        +for id in tracing_ids {
        +    // Query tracing info from system_traces.sessions and system_traces.events
        +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
        +    println!("tracing_info: {:#?}", tracing_info);
        +}
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/tracing/query-history.html b/stable/tracing/query-history.html new file mode 100644 index 0000000000..9b513ebd24 --- /dev/null +++ b/stable/tracing/query-history.html @@ -0,0 +1,733 @@ + + + + + + + + + + + + + Query Execution History | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Query Execution History

        +

        The driver allows to collect history of query execution.
        +This history includes all requests sent, decisions to retry and speculative execution fibers started.

        +
        +

        Example code

        +
        use scylla::query::Query;
        +use scylla::history::{HistoryCollector, StructuredHistory};
        +use std::sync::Arc;
        +
        +// Create a query for which we would like to trace the history of its execution
        +let mut query: Query = Query::new("SELECT * FROM ks.t");
        +
        +// Create a history collector and pass it to the query
        +let history_listener = Arc::new(HistoryCollector::new());
        +query.set_history_listener(history_listener.clone());
        +
        +// Run the query, doesn't matter if it failed, the history will still be saved
        +let _ignore_error = session.query(query.clone(), ()).await;
        +
        +// Access the collected history and print it
        +let structured_history: StructuredHistory = history_listener.clone_structured_history();
        +println!("Query history: {}", structured_history);
        +
        +
        +

        To see more check out the example code

        +
        +
        +

        Output

        +

        Sample output for a query that didn’t encounter any difficulties:

        +
        === Query #0 ===
        +| start_time: 2022-08-25 11:21:50.445075147 UTC
        +| Non-speculative attempts:
        +| - Attempt #0 sent to 127.0.0.1:9042
        +|   request send time: 2022-08-25 11:21:50.445151628 UTC
        +|   Success at 2022-08-25 11:21:50.447444362 UTC
        +|
        +| Query successful at 2022-08-25 11:21:50.447447970 UTC
        +=================
        +
        +
        +

        Here’s output for a query that had some trouble - nodes didn’t respond and speculative execution decided to query others in parallel. +Finally the third node provided a response.

        +
        === Query #0 ===
        +| start_time: 2022-08-26 15:08:28.525367409 UTC
        +| Non-speculative attempts:
        +| - Attempt #0 sent to 127.0.0.219:9042
        +|   request send time: 2022-08-26 15:08:28.525409294 UTC
        +|   No result yet
        +|
        +|
        +| > Speculative fiber #0
        +| fiber start time: 2022-08-26 15:08:28.537074167 UTC
        +| - Attempt #0 sent to 127.0.0.217:9042
        +|   request send time: 2022-08-26 15:08:28.537126083 UTC
        +|   No result yet
        +|
        +|
        +| > Speculative fiber #1
        +| fiber start time: 2022-08-26 15:08:28.548050242 UTC
        +| - Attempt #0 sent to 127.0.0.218:9042
        +|   request send time: 2022-08-26 15:08:28.548089083 UTC
        +|   Success at 2022-08-26 15:08:28.590052778 UTC
        +|
        +| Query successful at 2022-08-26 15:08:28.590078119 UTC
        +=================
        +
        +
        +
        +
        +

        How the driver executes queries

        +

        To read the output it’s useful to understand more about how the driver executes queries.

        +
        +

        No speculative execution

        +

        Without speculative execution the driver performs many attempts sequentially until one of them succeeds. +A single attempt consists of sending a request to some node and waiting for the answer. +In case of an error the driver consults the retry policy to decide what to do next. +The decision might be to fail the query, retry on the same node, another node, change query parameters, etc. +Once the decision is made either the query fails or another attempt is started. This continues until the query ends.

        +
        +
        +

        Speculative execution

        +

        When speculative execution is enabled at first the driver doesn’t care about it - it does the attempts sequentially and tries to get an answer. +However once a specified amount of time has passed it will decide to try new attempts in parallel +hoping that another node will be able to answer quicker. +This is done by spawning a speculative fiber. Each spawned fiber performs sequential attempts just like in non-speculative execution. +Many fibers can be spawned if the answer wasn’t acquired in time.

        +
        +
        +

        StructuredHistory

        +

        StructuredHistory +is a history representation that represents the history by listing attempts for each speculative fiber.

        +
        +
        +
        +

        HistoryListener trait, custom history collecting

        +

        History can be collected by any struct implementing the +HistoryListener trait.

        +

        The implementation of HistoryListener provided by this crate is the +HistoryCollector. +HistoryCollector simply collects all events along with their timestamps.

        +

        Information collected by HistoryCollector is just a stream of events, in order to analyze it it’s possible +to convert it to a structured representation. +StructuredHistory +can be created by calling HistoryCollector::clone_structured_history().

        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/stable/tracing/tracing.html b/stable/tracing/tracing.html new file mode 100644 index 0000000000..51d14af7df --- /dev/null +++ b/stable/tracing/tracing.html @@ -0,0 +1,645 @@ + + + + + + + + + + + + + Query tracing | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + +
        +
        + Menu +
        +
        +
        +
        +
        + + + + +
        + +
        + +
        +

        Query tracing

        +

        The driver has utilities for monitoring the execution of queries. +There are two separate ways to get information about what happened with a query: Tracing and Query Execution History.

        +
        +

        Tracing

        +

        Tracing is a feature provided by Scylla. When sending a query we can set a flag that signifies that we would like it to be traced. +After completing the query Scylla provides a tracing_id which can be used to fetch information about it - which nodes it was sent to, what operations were performed etc.

        +

        Queries that support tracing:

        + +

        After obtaining the tracing id you can use Session::get_tracing_info() to query tracing information.
        +TracingInfo contains values that are the same in Scylla and Cassandra®, skipping any database-specific ones.
        +If TracingInfo does not contain some needed value it’s possible to query it manually from the tables +system_traces.sessions and system_traces.events

        +
        +
        +

        Query Execution History

        +

        Tracing provides information about how the query execution went on database nodes, but it doesn’t say anything about what was going on inside the driver.
        +This is what query execution history was made for.

        +

        It allows to follow what the driver was thinking - all query attempts, retry decisions, speculative executions. +More information is available in the Query Execution History chapter.

        +
        +
        +
        +
        + + +
        + + + + + + + +
        + +
        + + + + +
        + + + + + + + \ No newline at end of file diff --git a/v0.12.0/.buildinfo b/v0.12.0/.buildinfo new file mode 100644 index 0000000000..b626415432 --- /dev/null +++ b/v0.12.0/.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: 42d809fc8b7b69b1d7cd18c9bbb2bf37 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/v0.12.0/.doctrees/connecting/authentication.doctree b/v0.12.0/.doctrees/connecting/authentication.doctree new file mode 100644 index 0000000000..409629aa2a Binary files /dev/null and b/v0.12.0/.doctrees/connecting/authentication.doctree differ diff --git a/v0.12.0/.doctrees/connecting/compression.doctree b/v0.12.0/.doctrees/connecting/compression.doctree new file mode 100644 index 0000000000..0be438ad28 Binary files /dev/null and b/v0.12.0/.doctrees/connecting/compression.doctree differ diff --git a/v0.12.0/.doctrees/connecting/connecting.doctree b/v0.12.0/.doctrees/connecting/connecting.doctree new file mode 100644 index 0000000000..74a1fcbc05 Binary files /dev/null and b/v0.12.0/.doctrees/connecting/connecting.doctree differ diff --git a/v0.12.0/.doctrees/connecting/tls.doctree b/v0.12.0/.doctrees/connecting/tls.doctree new file mode 100644 index 0000000000..d24309f961 Binary files /dev/null and b/v0.12.0/.doctrees/connecting/tls.doctree differ diff --git a/v0.12.0/.doctrees/contents.doctree b/v0.12.0/.doctrees/contents.doctree new file mode 100644 index 0000000000..cb0e6a8322 Binary files /dev/null and b/v0.12.0/.doctrees/contents.doctree differ diff --git a/v0.12.0/.doctrees/data-types/blob.doctree b/v0.12.0/.doctrees/data-types/blob.doctree new file mode 100644 index 0000000000..e3b3215abc Binary files /dev/null and b/v0.12.0/.doctrees/data-types/blob.doctree differ diff --git a/v0.12.0/.doctrees/data-types/collections.doctree b/v0.12.0/.doctrees/data-types/collections.doctree new file mode 100644 index 0000000000..4e7739988f Binary files /dev/null and b/v0.12.0/.doctrees/data-types/collections.doctree differ diff --git a/v0.12.0/.doctrees/data-types/counter.doctree b/v0.12.0/.doctrees/data-types/counter.doctree new file mode 100644 index 0000000000..7204d4dea2 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/counter.doctree differ diff --git a/v0.12.0/.doctrees/data-types/data-types.doctree b/v0.12.0/.doctrees/data-types/data-types.doctree new file mode 100644 index 0000000000..106da5432d Binary files /dev/null and b/v0.12.0/.doctrees/data-types/data-types.doctree differ diff --git a/v0.12.0/.doctrees/data-types/date.doctree b/v0.12.0/.doctrees/data-types/date.doctree new file mode 100644 index 0000000000..cccbb44476 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/date.doctree differ diff --git a/v0.12.0/.doctrees/data-types/decimal.doctree b/v0.12.0/.doctrees/data-types/decimal.doctree new file mode 100644 index 0000000000..dc2f865ea4 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/decimal.doctree differ diff --git a/v0.12.0/.doctrees/data-types/duration.doctree b/v0.12.0/.doctrees/data-types/duration.doctree new file mode 100644 index 0000000000..ed512c1ec4 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/duration.doctree differ diff --git a/v0.12.0/.doctrees/data-types/inet.doctree b/v0.12.0/.doctrees/data-types/inet.doctree new file mode 100644 index 0000000000..4b669a35cf Binary files /dev/null and b/v0.12.0/.doctrees/data-types/inet.doctree differ diff --git a/v0.12.0/.doctrees/data-types/primitive.doctree b/v0.12.0/.doctrees/data-types/primitive.doctree new file mode 100644 index 0000000000..27ff454de3 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/primitive.doctree differ diff --git a/v0.12.0/.doctrees/data-types/text.doctree b/v0.12.0/.doctrees/data-types/text.doctree new file mode 100644 index 0000000000..50fb0f37df Binary files /dev/null and b/v0.12.0/.doctrees/data-types/text.doctree differ diff --git a/v0.12.0/.doctrees/data-types/time.doctree b/v0.12.0/.doctrees/data-types/time.doctree new file mode 100644 index 0000000000..e41c17016e Binary files /dev/null and b/v0.12.0/.doctrees/data-types/time.doctree differ diff --git a/v0.12.0/.doctrees/data-types/timestamp.doctree b/v0.12.0/.doctrees/data-types/timestamp.doctree new file mode 100644 index 0000000000..80fd7a9347 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/timestamp.doctree differ diff --git a/v0.12.0/.doctrees/data-types/timeuuid.doctree b/v0.12.0/.doctrees/data-types/timeuuid.doctree new file mode 100644 index 0000000000..e03e0fe8f4 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/timeuuid.doctree differ diff --git a/v0.12.0/.doctrees/data-types/tuple.doctree b/v0.12.0/.doctrees/data-types/tuple.doctree new file mode 100644 index 0000000000..b2be111997 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/tuple.doctree differ diff --git a/v0.12.0/.doctrees/data-types/udt.doctree b/v0.12.0/.doctrees/data-types/udt.doctree new file mode 100644 index 0000000000..deb452e766 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/udt.doctree differ diff --git a/v0.12.0/.doctrees/data-types/uuid.doctree b/v0.12.0/.doctrees/data-types/uuid.doctree new file mode 100644 index 0000000000..89d904fb0b Binary files /dev/null and b/v0.12.0/.doctrees/data-types/uuid.doctree differ diff --git a/v0.12.0/.doctrees/data-types/varint.doctree b/v0.12.0/.doctrees/data-types/varint.doctree new file mode 100644 index 0000000000..a66c73aa48 Binary files /dev/null and b/v0.12.0/.doctrees/data-types/varint.doctree differ diff --git a/v0.12.0/.doctrees/environment.pickle b/v0.12.0/.doctrees/environment.pickle new file mode 100644 index 0000000000..5795bbfe3e Binary files /dev/null and b/v0.12.0/.doctrees/environment.pickle differ diff --git a/v0.12.0/.doctrees/execution-profiles/create-and-use.doctree b/v0.12.0/.doctrees/execution-profiles/create-and-use.doctree new file mode 100644 index 0000000000..2fcc9d7e2c Binary files /dev/null and b/v0.12.0/.doctrees/execution-profiles/create-and-use.doctree differ diff --git a/v0.12.0/.doctrees/execution-profiles/execution-profiles.doctree b/v0.12.0/.doctrees/execution-profiles/execution-profiles.doctree new file mode 100644 index 0000000000..cdd3948f35 Binary files /dev/null and b/v0.12.0/.doctrees/execution-profiles/execution-profiles.doctree differ diff --git a/v0.12.0/.doctrees/execution-profiles/maximal-example.doctree b/v0.12.0/.doctrees/execution-profiles/maximal-example.doctree new file mode 100644 index 0000000000..724706a8f7 Binary files /dev/null and b/v0.12.0/.doctrees/execution-profiles/maximal-example.doctree differ diff --git a/v0.12.0/.doctrees/execution-profiles/priority.doctree b/v0.12.0/.doctrees/execution-profiles/priority.doctree new file mode 100644 index 0000000000..df6fe8cbae Binary files /dev/null and b/v0.12.0/.doctrees/execution-profiles/priority.doctree differ diff --git a/v0.12.0/.doctrees/execution-profiles/remap.doctree b/v0.12.0/.doctrees/execution-profiles/remap.doctree new file mode 100644 index 0000000000..54fc4f3aa6 Binary files /dev/null and b/v0.12.0/.doctrees/execution-profiles/remap.doctree differ diff --git a/v0.12.0/.doctrees/index.doctree b/v0.12.0/.doctrees/index.doctree new file mode 100644 index 0000000000..413fa4f5fc Binary files /dev/null and b/v0.12.0/.doctrees/index.doctree differ diff --git a/v0.12.0/.doctrees/load-balancing/default-policy.doctree b/v0.12.0/.doctrees/load-balancing/default-policy.doctree new file mode 100644 index 0000000000..6cd7d7e97d Binary files /dev/null and b/v0.12.0/.doctrees/load-balancing/default-policy.doctree differ diff --git a/v0.12.0/.doctrees/load-balancing/load-balancing.doctree b/v0.12.0/.doctrees/load-balancing/load-balancing.doctree new file mode 100644 index 0000000000..b54cda9049 Binary files /dev/null and b/v0.12.0/.doctrees/load-balancing/load-balancing.doctree differ diff --git a/v0.12.0/.doctrees/logging/logging.doctree b/v0.12.0/.doctrees/logging/logging.doctree new file mode 100644 index 0000000000..df2d3b270b Binary files /dev/null and b/v0.12.0/.doctrees/logging/logging.doctree differ diff --git a/v0.12.0/.doctrees/metrics/metrics.doctree b/v0.12.0/.doctrees/metrics/metrics.doctree new file mode 100644 index 0000000000..cd6f293073 Binary files /dev/null and b/v0.12.0/.doctrees/metrics/metrics.doctree differ diff --git a/v0.12.0/.doctrees/migration-guides/0.11-serialization.doctree b/v0.12.0/.doctrees/migration-guides/0.11-serialization.doctree new file mode 100644 index 0000000000..f61e076207 Binary files /dev/null and b/v0.12.0/.doctrees/migration-guides/0.11-serialization.doctree differ diff --git a/v0.12.0/.doctrees/migration-guides/migration-guides.doctree b/v0.12.0/.doctrees/migration-guides/migration-guides.doctree new file mode 100644 index 0000000000..1756faf80c Binary files /dev/null and b/v0.12.0/.doctrees/migration-guides/migration-guides.doctree differ diff --git a/v0.12.0/.doctrees/queries/batch.doctree b/v0.12.0/.doctrees/queries/batch.doctree new file mode 100644 index 0000000000..570fe7332e Binary files /dev/null and b/v0.12.0/.doctrees/queries/batch.doctree differ diff --git a/v0.12.0/.doctrees/queries/lwt.doctree b/v0.12.0/.doctrees/queries/lwt.doctree new file mode 100644 index 0000000000..96c2980955 Binary files /dev/null and b/v0.12.0/.doctrees/queries/lwt.doctree differ diff --git a/v0.12.0/.doctrees/queries/paged.doctree b/v0.12.0/.doctrees/queries/paged.doctree new file mode 100644 index 0000000000..cfc0e289c2 Binary files /dev/null and b/v0.12.0/.doctrees/queries/paged.doctree differ diff --git a/v0.12.0/.doctrees/queries/prepared.doctree b/v0.12.0/.doctrees/queries/prepared.doctree new file mode 100644 index 0000000000..ed859dec48 Binary files /dev/null and b/v0.12.0/.doctrees/queries/prepared.doctree differ diff --git a/v0.12.0/.doctrees/queries/queries.doctree b/v0.12.0/.doctrees/queries/queries.doctree new file mode 100644 index 0000000000..7217fc2dd9 Binary files /dev/null and b/v0.12.0/.doctrees/queries/queries.doctree differ diff --git a/v0.12.0/.doctrees/queries/result.doctree b/v0.12.0/.doctrees/queries/result.doctree new file mode 100644 index 0000000000..827a31f79a Binary files /dev/null and b/v0.12.0/.doctrees/queries/result.doctree differ diff --git a/v0.12.0/.doctrees/queries/schema-agreement.doctree b/v0.12.0/.doctrees/queries/schema-agreement.doctree new file mode 100644 index 0000000000..b0ebe342d5 Binary files /dev/null and b/v0.12.0/.doctrees/queries/schema-agreement.doctree differ diff --git a/v0.12.0/.doctrees/queries/simple.doctree b/v0.12.0/.doctrees/queries/simple.doctree new file mode 100644 index 0000000000..24a26fd46a Binary files /dev/null and b/v0.12.0/.doctrees/queries/simple.doctree differ diff --git a/v0.12.0/.doctrees/queries/timeouts.doctree b/v0.12.0/.doctrees/queries/timeouts.doctree new file mode 100644 index 0000000000..9e424c079e Binary files /dev/null and b/v0.12.0/.doctrees/queries/timeouts.doctree differ diff --git a/v0.12.0/.doctrees/queries/usekeyspace.doctree b/v0.12.0/.doctrees/queries/usekeyspace.doctree new file mode 100644 index 0000000000..9b7d4ad66a Binary files /dev/null and b/v0.12.0/.doctrees/queries/usekeyspace.doctree differ diff --git a/v0.12.0/.doctrees/queries/values.doctree b/v0.12.0/.doctrees/queries/values.doctree new file mode 100644 index 0000000000..0f9067c189 Binary files /dev/null and b/v0.12.0/.doctrees/queries/values.doctree differ diff --git a/v0.12.0/.doctrees/quickstart/create-project.doctree b/v0.12.0/.doctrees/quickstart/create-project.doctree new file mode 100644 index 0000000000..1b15452271 Binary files /dev/null and b/v0.12.0/.doctrees/quickstart/create-project.doctree differ diff --git a/v0.12.0/.doctrees/quickstart/example.doctree b/v0.12.0/.doctrees/quickstart/example.doctree new file mode 100644 index 0000000000..e9fd8ca2e1 Binary files /dev/null and b/v0.12.0/.doctrees/quickstart/example.doctree differ diff --git a/v0.12.0/.doctrees/quickstart/quickstart.doctree b/v0.12.0/.doctrees/quickstart/quickstart.doctree new file mode 100644 index 0000000000..c5896eb07c Binary files /dev/null and b/v0.12.0/.doctrees/quickstart/quickstart.doctree differ diff --git a/v0.12.0/.doctrees/quickstart/scylla-docker.doctree b/v0.12.0/.doctrees/quickstart/scylla-docker.doctree new file mode 100644 index 0000000000..7eda34d647 Binary files /dev/null and b/v0.12.0/.doctrees/quickstart/scylla-docker.doctree differ diff --git a/v0.12.0/.doctrees/retry-policy/default.doctree b/v0.12.0/.doctrees/retry-policy/default.doctree new file mode 100644 index 0000000000..78352beb5f Binary files /dev/null and b/v0.12.0/.doctrees/retry-policy/default.doctree differ diff --git a/v0.12.0/.doctrees/retry-policy/downgrading-consistency.doctree b/v0.12.0/.doctrees/retry-policy/downgrading-consistency.doctree new file mode 100644 index 0000000000..f01d1067a2 Binary files /dev/null and b/v0.12.0/.doctrees/retry-policy/downgrading-consistency.doctree differ diff --git a/v0.12.0/.doctrees/retry-policy/fallthrough.doctree b/v0.12.0/.doctrees/retry-policy/fallthrough.doctree new file mode 100644 index 0000000000..5e2403d74d Binary files /dev/null and b/v0.12.0/.doctrees/retry-policy/fallthrough.doctree differ diff --git a/v0.12.0/.doctrees/retry-policy/retry-policy.doctree b/v0.12.0/.doctrees/retry-policy/retry-policy.doctree new file mode 100644 index 0000000000..ce9044fd29 Binary files /dev/null and b/v0.12.0/.doctrees/retry-policy/retry-policy.doctree differ diff --git a/v0.12.0/.doctrees/schema/schema.doctree b/v0.12.0/.doctrees/schema/schema.doctree new file mode 100644 index 0000000000..6404255d57 Binary files /dev/null and b/v0.12.0/.doctrees/schema/schema.doctree differ diff --git a/v0.12.0/.doctrees/speculative-execution/percentile.doctree b/v0.12.0/.doctrees/speculative-execution/percentile.doctree new file mode 100644 index 0000000000..061ca1f1e9 Binary files /dev/null and b/v0.12.0/.doctrees/speculative-execution/percentile.doctree differ diff --git a/v0.12.0/.doctrees/speculative-execution/simple.doctree b/v0.12.0/.doctrees/speculative-execution/simple.doctree new file mode 100644 index 0000000000..a0e1015a8a Binary files /dev/null and b/v0.12.0/.doctrees/speculative-execution/simple.doctree differ diff --git a/v0.12.0/.doctrees/speculative-execution/speculative.doctree b/v0.12.0/.doctrees/speculative-execution/speculative.doctree new file mode 100644 index 0000000000..728d3eaf91 Binary files /dev/null and b/v0.12.0/.doctrees/speculative-execution/speculative.doctree differ diff --git a/v0.12.0/.doctrees/tracing/basic.doctree b/v0.12.0/.doctrees/tracing/basic.doctree new file mode 100644 index 0000000000..45aa4b8f6e Binary files /dev/null and b/v0.12.0/.doctrees/tracing/basic.doctree differ diff --git a/v0.12.0/.doctrees/tracing/paged.doctree b/v0.12.0/.doctrees/tracing/paged.doctree new file mode 100644 index 0000000000..ef1097b61d Binary files /dev/null and b/v0.12.0/.doctrees/tracing/paged.doctree differ diff --git a/v0.12.0/.doctrees/tracing/prepare.doctree b/v0.12.0/.doctrees/tracing/prepare.doctree new file mode 100644 index 0000000000..123b2b579d Binary files /dev/null and b/v0.12.0/.doctrees/tracing/prepare.doctree differ diff --git a/v0.12.0/.doctrees/tracing/query-history.doctree b/v0.12.0/.doctrees/tracing/query-history.doctree new file mode 100644 index 0000000000..c9c3685381 Binary files /dev/null and b/v0.12.0/.doctrees/tracing/query-history.doctree differ diff --git a/v0.12.0/.doctrees/tracing/tracing.doctree b/v0.12.0/.doctrees/tracing/tracing.doctree new file mode 100644 index 0000000000..4e66c7ed07 Binary files /dev/null and b/v0.12.0/.doctrees/tracing/tracing.doctree differ diff --git a/v0.12.0/.nojekyll b/v0.12.0/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/v0.12.0/404.html b/v0.12.0/404.html new file mode 100644 index 0000000000..e283e2eea9 --- /dev/null +++ b/v0.12.0/404.html @@ -0,0 +1,31 @@ + + + + + + + + + ScyllaDB + + + + + + + + + + + +
        +

        404

        +

        The ScyllaDB monster ate your page!

        +

        + Home +

        +
        + + + \ No newline at end of file diff --git a/v0.12.0/CNAME b/v0.12.0/CNAME new file mode 100644 index 0000000000..63858016cb --- /dev/null +++ b/v0.12.0/CNAME @@ -0,0 +1 @@ +rust-driver.docs.scylladb.com \ No newline at end of file diff --git a/v0.12.0/_sources/connecting/authentication.md.txt b/v0.12.0/_sources/connecting/authentication.md.txt new file mode 100644 index 0000000000..a18ace127a --- /dev/null +++ b/v0.12.0/_sources/connecting/authentication.md.txt @@ -0,0 +1,79 @@ +# Authentication + +Driver supports both authentication by username and password and custom authentication defined by a user. +###### Important: The default authentication credentials are sent in plain text to the server. For this reason, it is highly recommended that this be used in conjunction with client-to-node encryption (SSL), or in a trusted network environment. + +To use the default authentication, specify credentials using the `user` method in `SessionBuilder`: + +```rust +use scylla::{Session, SessionBuilder}; + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .user("myusername", "mypassword") + .build() + .await?; + +``` + ### Custom Authentication + +A custom authentication is defined by implementing the `AuthenticatorSession`. +An `AuthenticatorSession` instance is created per session, so it is also necessary to define a `AuthenticatorProvider` for it. +Finally, to make use of the custom authentication, use the `authenticator_provider` method in `SessionBuilder`: + +```rust +use bytes::{BufMut, BytesMut}; +use async_trait::async_trait; +use scylla::authentication::{AuthError, AuthenticatorProvider, AuthenticatorSession}; + +struct CustomAuthenticator; + +#[async_trait] +impl AuthenticatorSession for CustomAuthenticator { + // to handle an authentication challenge initiated by the server. + // The information contained in the token parameter is authentication protocol specific. + // It may be NULL or empty. + async fn evaluate_challenge( + &mut self, + _token: Option<&[u8]>, + ) -> Result>, AuthError> { + Err("Challenges are not expected".to_string()) + } + + // to handle the success phase of exchange. The token parameters contain information that may be used to finalize the request. + async fn success(&mut self, _token: Option<&[u8]>) -> Result<(), AuthError> { + Ok(()) + } +} + +struct CustomAuthenticatorProvider; + +#[async_trait] +impl AuthenticatorProvider for CustomAuthenticatorProvider { + async fn start_authentication_session( + &self, + _name: &str, + ) -> Result<(Option>, Box), AuthError> { + let mut response = BytesMut::new(); + let cred = "\0cassandra\0cassandra"; + let cred_length = 20; + + response.put_i32(cred_length); + response.put_slice(cred.as_bytes()); + + Ok((Some(response.to_vec()), Box::new(CustomAuthenticator))) + } +} + +async fn authentication_example() -> Result<(), Box> { + use scylla::{Session, SessionBuilder}; + + let _session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .authenticator_provider(Arc::new(CustomAuthenticatorProvider)) + .build() + .await?; + + Ok(()) +} +``` diff --git a/v0.12.0/_sources/connecting/compression.md.txt b/v0.12.0/_sources/connecting/compression.md.txt new file mode 100644 index 0000000000..4ba755e47c --- /dev/null +++ b/v0.12.0/_sources/connecting/compression.md.txt @@ -0,0 +1,30 @@ +# Compression + +By default the driver does not use any compression on connections.\ +It's possible to specify a preferred compression algorithm. \ +The driver will try using it, but if the database doesn't support it, it will fall back to no compression. + +Available compression algorithms: +* Snappy +* LZ4 + +An example enabling `Snappy` compression algorithm: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::Compression; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .compression(Some(Compression::Snappy)) + .build() + .await?; + + Ok(()) +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/connecting/connecting.md.txt b/v0.12.0/_sources/connecting/connecting.md.txt new file mode 100644 index 0000000000..04b64be099 --- /dev/null +++ b/v0.12.0/_sources/connecting/connecting.md.txt @@ -0,0 +1,110 @@ +# Connecting to the cluster + +Scylla is a distributed database, which means that it operates on multiple nodes running independently. +When creating a `Session` you can specify a few known nodes to which the driver will try connecting: +```rust +use scylla::{Session, SessionBuilder}; +use std::error::Error; +use std::time::Duration; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .known_node("127.0.0.72:4321") + .known_node("localhost:8000") + .connection_timeout(Duration::from_secs(3)) + .cluster_metadata_refresh_interval(Duration::from_secs(10)) + .known_node_addr(SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), + 9000, + )) + .build() + .await?; + + Ok(()) +} +``` + +After successfully connecting to some specified node the driver will fetch topology information about +other nodes in this cluster and connect to them as well. + +## Best practices for using Session + +:::{warning} +Always try to use only a single Session object per apllication because creating them is very expensive! +::: + +The driver maintains its own pool of connections to each node and each connection is capable of handling multiple requests in parallel. Driver will also route requests to nodes / shards that actually own the data (unless the load balancing policy that you use doesn't support it). + +For those reasons, we recommend using one instance of `Session` per application. + +Creating short-lived `Session`'s (e.g. `Session` per request) is strongly discouraged because it will result in great performance penalties because creating a `Session` is a costly process - it requires estabilishing a lot of TCP connections. +Creating many `Session`'s in one application (e.g. `Session` per thread / per Tokio task) is also discouraged, because it wastes resources - as mentioned before, `Session` maintains a connection pool itself and can handle parallel queries, so you would be holding a lot of connections unnecessarily. + +If you need to share `Session` with different threads / Tokio tasks etc. use `Arc` - all methods of `Session` take `&self`, so it doesn't hinder the functionality in any way. + +## Metadata + +The driver refreshes the cluster metadata periodically, which contains information about cluster topology as well as the cluster schema. By default, the driver refreshes the cluster metadata every 60 seconds. +However, you can set the `cluster_metadata_refresh_interval` to a non-negative value to periodically refresh the cluster metadata. This is useful when you do not have unexpected amount of traffic or when you have an extra traffic causing topology to change frequently. + +## Scylla Cloud Serverless + +Scylla Serverless is an elastic and dynamic deployment model. When creating a `Session` you need to +specify the secure connection bundle as follows: + +```rust +use std::path::Path; +use std::error::Error; +use scylla::CloudSessionBuilder; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let session = CloudSessionBuilder::new(Path::new("config_data.yaml")) + .unwrap() + .build() + .await + .unwrap(); + + Ok(()) +} +``` + +Note that the bundle file will be provided after the serverless cluster is created. Here is an example of a +configuration file for a serverless cluster: + +```yaml +datacenters: + datacenter1: + certificateAuthorityData: CERTIFICATE_DATA + server: 127.0.1.1:9142 + nodeDomain: cql.cluster-id.scylla.com + insecureSkipTlsVerify: false +authInfos: + default: + clientCertificateData: CERTIFICATE_DATA + clientKeyData: KEY_DATA + username: scylladb + password: scylladb +contexts: + default: + datacenterName: datacenter1 + authInfoName: default +currentContext: default +``` + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + compression + authentication + tls + +``` \ No newline at end of file diff --git a/v0.12.0/_sources/connecting/tls.md.txt b/v0.12.0/_sources/connecting/tls.md.txt new file mode 100644 index 0000000000..86f9379955 --- /dev/null +++ b/v0.12.0/_sources/connecting/tls.md.txt @@ -0,0 +1,63 @@ +# TLS + +Driver uses the [`openssl`](https://github.com/sfackler/rust-openssl) crate for TLS functionality.\ +It was chosen because [`rustls`](https://github.com/ctz/rustls) doesn't support certificates for ip addresses +(see [issue](https://github.com/briansmith/webpki/issues/54)), which is a common use case for Scylla. + + +### Enabling feature +`openssl` is not a pure Rust library so you need enable a feature and install the proper package. + +To enable the `tls` feature add in `Cargo.toml`: +```toml +scylla = { version = "0.4", features = ["ssl"] } +openssl = "0.10.32" +``` + +Then install the package with `openssl`: +* Debian/Ubuntu: + ```bash + apt install libssl-dev pkg-config + ``` +* Fedora: + ```bash + dnf install openssl-devel + ``` + +* Arch: + ```bash + pacman -S openssl pkg-config + ``` + +### Using TLS +To use tls you will have to create an openssl +[`SslContext`](https://docs.rs/openssl/0.10.33/openssl/ssl/struct.SslContext.html) +and pass it to `SessionBuilder` + +For example, if database certificate is in the file `ca.crt`: +```rust +use scylla::{Session, SessionBuilder}; +use openssl::ssl::{SslContextBuilder, SslMethod, SslVerifyMode}; +use std::path::PathBuf; + +let mut context_builder = SslContextBuilder::new(SslMethod::tls())?; +context_builder.set_ca_file("ca.crt")?; +context_builder.set_verify(SslVerifyMode::PEER); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9142") // The the port is now 9142 + .ssl_context(Some(context_builder.build())) + .build() + .await?; + +``` + +See the full [example](https://github.com/scylladb/scylla-rust-driver/blob/main/examples/tls.rs) for more details diff --git a/v0.12.0/_sources/contents.rst.txt b/v0.12.0/_sources/contents.rst.txt new file mode 100644 index 0000000000..5bc4a37c9e --- /dev/null +++ b/v0.12.0/_sources/contents.rst.txt @@ -0,0 +1,19 @@ +.. toctree:: + :hidden: + :glob: + :titlesonly: + + index + quickstart/quickstart + connecting/connecting + queries/queries + execution-profiles/execution-profiles + data-types/data-types + load-balancing/load-balancing + retry-policy/retry-policy + speculative-execution/speculative + metrics/metrics + migration-guides/migration-guides + logging/logging + tracing/tracing + schema/schema diff --git a/v0.12.0/_sources/data-types/blob.md.txt b/v0.12.0/_sources/data-types/blob.md.txt new file mode 100644 index 0000000000..550c5f27f7 --- /dev/null +++ b/v0.12.0/_sources/data-types/blob.md.txt @@ -0,0 +1,21 @@ +# Blob +`Blob` is represented as `Vec` + + +```rust +use scylla::IntoTypedRows; + +// Insert some blob into the table as a Vec +// We can insert it by reference to not move the whole blob +let to_insert: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&to_insert,)) + .await?; + +// Read blobs from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(Vec,)>() { + let (blob_value,): (Vec,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/collections.md.txt b/v0.12.0/_sources/data-types/collections.md.txt new file mode 100644 index 0000000000..91ec36d0ee --- /dev/null +++ b/v0.12.0/_sources/data-types/collections.md.txt @@ -0,0 +1,120 @@ +# List, Set, Map + +## List +`List` is represented as `Vec` + +```rust +use scylla::IntoTypedRows; + +// Insert a list of ints into the table +let my_list: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_list,)) + .await?; + +// Read a list of ints from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(Vec,)>() { + let (list_value,): (Vec,) = row?; + } +} +``` + +## Set +`Set` is represented as `Vec`, `HashSet` or `BTreeSet`: + +```rust +use scylla::IntoTypedRows; + +// Insert a set of ints into the table +let my_set: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(Vec,)>() { + let (set_value,): (Vec,) = row?; + } +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::HashSet; + +// Insert a set of ints into the table +let my_set: HashSet = vec![1, 2, 3, 4, 5].into_iter().collect(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(HashSet,)>() { + let (set_value,): (HashSet,) = row?; + } +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::BTreeSet; + +// Insert a set of ints into the table +let my_set: BTreeSet = vec![1, 2, 3, 4, 5].into_iter().collect(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(BTreeSet,)>() { + let (set_value,): (BTreeSet,) = row?; + } +} +``` + +## Map +`Map` is represented as `HashMap` or `BTreeMap` + +```rust +use scylla::IntoTypedRows; +use std::collections::HashMap; + +// Insert a map of text and int into the table +let mut my_map: HashMap = HashMap::new(); +my_map.insert("abcd".to_string(), 16); + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,)) + .await?; + +// Read a map from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(HashMap,)>() { + let (map_value,): (HashMap,) = row?; + } +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::BTreeMap; + +// Insert a map of text and int into the table +let mut my_map: BTreeMap = BTreeMap::new(); +my_map.insert("abcd".to_string(), 16); + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,)) + .await?; + +// Read a map from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(BTreeMap,)>() { + let (map_value,): (BTreeMap,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/counter.md.txt b/v0.12.0/_sources/data-types/counter.md.txt new file mode 100644 index 0000000000..321ef58ab8 --- /dev/null +++ b/v0.12.0/_sources/data-types/counter.md.txt @@ -0,0 +1,16 @@ +# Counter +`Counter` is represented as `struct Counter(pub i64)`\ +`Counter` can't be inserted, it can only be read or updated. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::Counter; + +// Read counter from the table +if let Some(rows) = session.query("SELECT c FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(Counter,)>() { + let (counter_value,): (Counter,) = row?; + let counter_int_value: i64 = counter_value.0; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/data-types.md.txt b/v0.12.0/_sources/data-types/data-types.md.txt new file mode 100644 index 0000000000..0d9696e765 --- /dev/null +++ b/v0.12.0/_sources/data-types/data-types.md.txt @@ -0,0 +1,60 @@ +# Data Types + +The driver maps database data types to matching Rust types +to achieve seamless sending and receiving of CQL values. + +See the following chapters for examples on how to send and receive each data type. + +See [Query values](../queries/values.md) for more information about sending values in queries.\ +See [Query result](../queries/result.md) for more information about reading values from queries + +Database types and their Rust equivalents: +* `Boolean` <----> `bool` +* `Tinyint` <----> `i8` +* `Smallint` <----> `i16` +* `Int` <----> `i32` +* `BigInt` <----> `i64` +* `Float` <----> `f32` +* `Double` <----> `f64` +* `Ascii`, `Text`, `Varchar` <----> `&str`, `String` +* `Counter` <----> `value::Counter` +* `Blob` <----> `Vec` +* `Inet` <----> `std::net::IpAddr` +* `Uuid` <----> `uuid::Uuid` +* `Timeuuid` <----> `value::CqlTimeuuid` +* `Date` <----> `value::CqlDate`, `chrono::NaiveDate`, `time::Date` +* `Time` <----> `value::CqlTime`, `chrono::NaiveTime`, `time::Time` +* `Timestamp` <----> `value::CqlTimestamp`, `chrono::DateTime`, `time::OffsetDateTime` +* `Duration` <----> `value::CqlDuration` +* `Decimal` <----> `value::CqlDecimal`, `bigdecimal::Decimal` +* `Varint` <----> `value::CqlVarint`, `num_bigint::BigInt` (v0.3 and v0.4) +* `List` <----> `Vec` +* `Set` <----> `Vec` +* `Map` <----> `std::collections::HashMap` +* `Tuple` <----> Rust tuples +* `UDT (User defined type)` <----> Custom user structs with macros + + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + primitive + text + counter + blob + inet + uuid + timeuuid + date + time + timestamp + duration + decimal + varint + collections + tuple + udt + +``` diff --git a/v0.12.0/_sources/data-types/date.md.txt b/v0.12.0/_sources/data-types/date.md.txt new file mode 100644 index 0000000000..7a7f0da51b --- /dev/null +++ b/v0.12.0/_sources/data-types/date.md.txt @@ -0,0 +1,99 @@ +# Date + +Depending on feature flags, three different types can be used to interact with date. + +Internally [date](https://docs.scylladb.com/stable/cql/types.html#dates) is represented as number of days since +-5877641-06-23 i.e. 2^31 days before unix epoch. + +## CqlDate + +Without any extra features enabled, only `frame::value::CqlDate` is available. It's an +[`u32`](https://doc.rust-lang.org/std/primitive.u32.html) wrapper and it matches the internal date representation. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlDate; +use scylla::IntoTypedRows; + +// 1970-01-08 +let to_insert = CqlDate((1 << 31) + 7); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read raw Date from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlDate,)>() { + let (date_value,): (CqlDate,) = row?; + } +} +``` + +## chrono::NaiveDate + +If full range is not required and `chrono` feature is enabled, +[`chrono::NaiveDate`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) can be used. +[`chrono::NaiveDate`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) supports dates from +-262145-01-01 to 262143-12-31. + +```rust +use chrono::NaiveDate; +use scylla::IntoTypedRows; + +// 2021-03-24 +let to_insert = NaiveDate::from_ymd_opt(2021, 3, 24).unwrap(); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read NaiveDate from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(NaiveDate,)>() { + let (date_value,): (NaiveDate,) = row?; + } +} +``` + +## time::Date + +Alternatively, `time` feature can be used to enable support of +[`time::Date`](https://docs.rs/time/0.3/time/struct.Date.html). +[`time::Date`](https://docs.rs/time/0.3/time/struct.Date.html)'s value range depends on feature flags, see its +documentation to get more info. + +```rust +use scylla::IntoTypedRows; +use time::{Date, Month}; + +// 2021-03-24 +let to_insert = Date::from_calendar_date(2021, Month::March, 24).unwrap(); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read Date from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(Date,)>() { + let (date_value,): (Date,) = row?; + } +} +``` diff --git a/v0.12.0/_sources/data-types/decimal.md.txt b/v0.12.0/_sources/data-types/decimal.md.txt new file mode 100644 index 0000000000..55eeaf87e7 --- /dev/null +++ b/v0.12.0/_sources/data-types/decimal.md.txt @@ -0,0 +1,49 @@ +# Decimal +`Decimal` is represented as `value::CqlDecimal` or [`bigdecimal::BigDecimal`](https://docs.rs/bigdecimal/latest/bigdecimal/struct.BigDecimal.html) + +## value::CqlDecimal + +Without any feature flags, the user can interact with `decimal` type by making use of `value::CqlDecimal` which is a very simple wrapper representing the value as signed binary number in big-endian order with a 32-bit scale. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlDecimal; +use std::str::FromStr; + +// Insert a decimal (123.456) into the table +let to_insert: CqlDecimal = + CqlDecimal::from_signed_be_bytes_and_exponent(vec![0x01, 0xE2, 0x40], 3); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a decimal from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(CqlDecimal,)>() { + let (decimal_value,): (CqlDecimal,) = row?; + } +} +``` + +## bigdecimal::BigDecimal + +To make use of `bigdecimal::Bigdecimal` type, user should enable `bigdecimal-04` crate feature. + +```rust +use scylla::IntoTypedRows; +use bigdecimal::BigDecimal; +use std::str::FromStr; + +// Insert a decimal into the table +let to_insert: BigDecimal = BigDecimal::from_str("12345.0")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a decimal from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(BigDecimal,)>() { + let (decimal_value,): (BigDecimal,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/duration.md.txt b/v0.12.0/_sources/data-types/duration.md.txt new file mode 100644 index 0000000000..e862420dbb --- /dev/null +++ b/v0.12.0/_sources/data-types/duration.md.txt @@ -0,0 +1,20 @@ +# Duration +`Duration` is represented as [`CqlDuration`](https://docs.rs/scylla/latest/scylla/frame/value/struct.CqlDuration.html)\ + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlDuration; + +// Insert some ip address into the table +let to_insert: CqlDuration = CqlDuration { months: 1, days: 2, nanoseconds: 3 }; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read inet from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(CqlDuration,)>() { + let (cql_duration,): (CqlDuration,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/inet.md.txt b/v0.12.0/_sources/data-types/inet.md.txt new file mode 100644 index 0000000000..92b2fab8cd --- /dev/null +++ b/v0.12.0/_sources/data-types/inet.md.txt @@ -0,0 +1,20 @@ +# Inet +`Inet` is represented as `std::net::IpAddr` + +```rust +use scylla::IntoTypedRows; +use std::net::{IpAddr, Ipv4Addr}; + +// Insert some ip address into the table +let to_insert: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read inet from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(IpAddr,)>() { + let (inet_value,): (IpAddr,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/primitive.md.txt b/v0.12.0/_sources/data-types/primitive.md.txt new file mode 100644 index 0000000000..28f3c5695f --- /dev/null +++ b/v0.12.0/_sources/data-types/primitive.md.txt @@ -0,0 +1,141 @@ +# Bool, Tinyint, Smallint, Int, Bigint, Float, Double + +### Bool +`Bool` is represented as rust `bool` + +```rust +use scylla::IntoTypedRows; + +// Insert a bool into the table +let to_insert: bool = true; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a bool from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(bool,)>() { + let (bool_value,): (bool,) = row?; + } +} +``` + +### Tinyint +`Tinyint` is represented as rust `i8` + +```rust +use scylla::IntoTypedRows; + +// Insert a tinyint into the table +let to_insert: i8 = 123; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a tinyint from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(i8,)>() { + let (tinyint_value,): (i8,) = row?; + } +} +``` + +### Smallint +`Smallint` is represented as rust `i16` + +```rust +use scylla::IntoTypedRows; + +// Insert a smallint into the table +let to_insert: i16 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a smallint from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(i16,)>() { + let (smallint_value,): (i16,) = row?; + } +} +``` + +### Int +`Int` is represented as rust `i32` + +```rust +use scylla::IntoTypedRows; + +// Insert an int into the table +let to_insert: i32 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read an int from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(i32,)>() { + let (int_value,): (i32,) = row?; + } +} +``` + +### Bigint +`Bigint` is represented as rust `i64` + +```rust +use scylla::IntoTypedRows; + +// Insert a bigint into the table +let to_insert: i64 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a bigint from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(i64,)>() { + let (bigint_value,): (i64,) = row?; + } +} +``` + +### Float +`Float` is represented as rust `f32` + +```rust +use scylla::IntoTypedRows; + +// Insert a float into the table +let to_insert: f32 = 123.0; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a float from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(f32,)>() { + let (float_value,): (f32,) = row?; + } +} +``` + +### Double +`Double` is represented as rust `f64` + +```rust +use scylla::IntoTypedRows; + +// Insert a double into the table +let to_insert: f64 = 12345.0; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a double from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(f64,)>() { + let (double_value,): (f64,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/text.md.txt b/v0.12.0/_sources/data-types/text.md.txt new file mode 100644 index 0000000000..8bbf41bdfa --- /dev/null +++ b/v0.12.0/_sources/data-types/text.md.txt @@ -0,0 +1,25 @@ +# Ascii, Text, Varchar +`Ascii`, `Text` and `Varchar` are represented as `&str` and `String` + +```rust +use scylla::IntoTypedRows; + +// Insert some text into the table as a &str +let to_insert_str: &str = "abcdef"; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_str,)) + .await?; + +// Insert some text into the table as a String +let to_insert_string: String = "abcdef".to_string(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_string,)) + .await?; + +// Read ascii/text/varchar from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(String,)>() { + let (text_value,): (String,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/time.md.txt b/v0.12.0/_sources/data-types/time.md.txt new file mode 100644 index 0000000000..637907030a --- /dev/null +++ b/v0.12.0/_sources/data-types/time.md.txt @@ -0,0 +1,97 @@ +# Time + +Depending on feature flags used, three different types can be used to interact with time. + +Internally [time](https://docs.scylladb.com/stable/cql/types.html#times) is represented as number of nanoseconds since +midnight. It can't be negative or exceed `86399999999999` (23:59:59.999999999). + +## CqlTime + +Without any extra features enabled, only `frame::value::CqlTime` is available. It's an +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) wrapper and it matches the internal time representation. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlTime; +use scylla::IntoTypedRows; + +// 64 seconds since midnight +let to_insert = CqlTime(64 * 1_000_000_000); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlTime,)>() { + let (time_value,): (CqlTime,) = row?; + } +} +``` + +## chrono::NaiveTime + +If `chrono` feature is enabled, [`chrono::NaiveTime`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) +can be used to interact with the database. Although chrono can represent leap seconds, they are not supported. +Attempts to convert [`chrono::NaiveTime`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) with leap +second to `CqlTime` or write it to the database will return an error. + +```rust +use chrono::NaiveTime; +use scylla::IntoTypedRows; + +// 01:02:03.456,789,012 +let to_insert = NaiveTime::from_hms_nano_opt(1, 2, 3, 456_789_012); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(NaiveTime,)>() { + let (time_value,): (NaiveTime,) = row?; + } +} +``` + +## time::Time + +If `time` feature is enabled, [`time::Time`](https://docs.rs/time/0.3/time/struct.Time.html) can be used to interact +with the database. + +```rust +use scylla::IntoTypedRows; +use time::Time; + +// 01:02:03.456,789,012 +let to_insert = Time::from_hms_nano(1, 2, 3, 456_789_012).unwrap(); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(Time,)>() { + let (time_value,): (Time,) = row?; + } +} +``` diff --git a/v0.12.0/_sources/data-types/timestamp.md.txt b/v0.12.0/_sources/data-types/timestamp.md.txt new file mode 100644 index 0000000000..fdfdbd7f4a --- /dev/null +++ b/v0.12.0/_sources/data-types/timestamp.md.txt @@ -0,0 +1,109 @@ +# Timestamp + +Depending on feature flags, three different types can be used to interact with timestamps. + +Internally [timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) is represented as +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) describing number of milliseconds since unix epoch. + +## CqlTimestamp + +Without any extra features enabled, only `frame::value::CqlTimestamp` is available. It's an +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) wrapper and it matches the internal time representation. It's +the only type that supports full range of values that database accepts. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlTimestamp; +use scylla::IntoTypedRows; + +// 64 seconds since unix epoch, 1970-01-01 00:01:04 +let to_insert = CqlTimestamp(64 * 1000); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlTimestamp,)>() { + let (timestamp_value,): (CqlTimestamp,) = row?; + } +} +``` + +## chrono::DateTime + +If full value range is not required, `chrono` feature can be used to enable support of +[`chrono::DateTime`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html). All values are expected to be converted +to UTC timezone explicitly, as [timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) doesn't store +timezone information. Any precision finer than 1ms will be lost. + +```rust +use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc}; +use scylla::IntoTypedRows; + +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123 +let to_insert = NaiveDateTime::new( + NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(), + NaiveTime::from_hms_milli_opt(0, 1, 4, 123).unwrap(), +) +.and_utc(); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(DateTime,)>() { + let (timestamp_value,): (DateTime,) = row?; + } +} +``` + +## time::OffsetDateTime + +Alternatively, `time` feature can be used to enable support of +[`time::OffsetDateTime`](https://docs.rs/time/0.3/time/struct.OffsetDateTime.html). As +[timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) doesn't support timezone information, time will +be corrected to UTC and timezone info will be erased on write. On read, UTC timestamp is returned. Any precision finer +than 1ms will also be lost. + +```rust +use scylla::IntoTypedRows; +use time::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time}; + +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123 +let to_insert = PrimitiveDateTime::new( + Date::from_calendar_date(1970, Month::January, 1).unwrap(), + Time::from_hms_milli(0, 1, 4, 123).unwrap(), +) +.assume_utc(); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(OffsetDateTime,)>() { + let (timestamp_value,): (OffsetDateTime,) = row?; + } +} +``` diff --git a/v0.12.0/_sources/data-types/timeuuid.md.txt b/v0.12.0/_sources/data-types/timeuuid.md.txt new file mode 100644 index 0000000000..147836543f --- /dev/null +++ b/v0.12.0/_sources/data-types/timeuuid.md.txt @@ -0,0 +1,23 @@ +# Timeuuid + +`Timeuuid` is represented as `value::CqlTimeuuid`. +`value::CqlTimeuuid` is a wrapper for `uuid::Uuid` with custom ordering logic +which follows Scylla/Cassandra semantics. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlTimeuuid; + +// Insert some timeuuid into the table +let to_insert: CqlTimeuuid = CqlTimeuuid::from_str("8e14e760-7fa8-11eb-bc66-000000000001")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timeuuid from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(CqlTimeuuid,)>() { + let (timeuuid_value,): (CqlTimeuuid,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/tuple.md.txt b/v0.12.0/_sources/data-types/tuple.md.txt new file mode 100644 index 0000000000..70a226300b --- /dev/null +++ b/v0.12.0/_sources/data-types/tuple.md.txt @@ -0,0 +1,22 @@ +# Tuple +`Tuple` is represented as rust tuples of max 16 elements. + +```rust +use scylla::IntoTypedRows; + +// Insert a tuple of int and string into the table +let to_insert: (i32, String) = (1, "abc".to_string()); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a tuple of int and string from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<((i32, String),)>() { + let (tuple_value,): ((i32, String),) = row?; + + let int_value: i32 = tuple_value.0; + let string_value: String = tuple_value.1; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/udt.md.txt b/v0.12.0/_sources/data-types/udt.md.txt new file mode 100644 index 0000000000..da02992827 --- /dev/null +++ b/v0.12.0/_sources/data-types/udt.md.txt @@ -0,0 +1,71 @@ +# User defined types +Scylla allows users to define their own data types with named fields (See [the official documentation](https://opensource.docs.scylladb.com/stable/cql/types.html#user-defined-types))\ +To use user defined types in the driver, you can create a corresponding struct in Rust, and use it to read and write UDT values. + + +For example let's say `my_type` was created using this query: +```sql +CREATE TYPE ks.my_type (int_val int, text_val text) +``` + +To use this type in the driver, create a matching struct and derive: +- `SerializeCql`: in order to be able to use this struct in query parameters. \ + This macro requires fields of UDT and struct to have matching names, but the order + of the fields is not required to be the same. \ + Note: you can use different name using `rename` attribute - see `SerializeCql` macro documentation. +- `FromUserType`: in order to be able to use this struct in query results. \ + This macro requires fields of UDT and struct to be in the same *ORDER*. \ + This mismatch between `SerializeCql` and `FromUserType` requirements is a temporary situation - in the future `FromUserType` (or the macro that replaces it) will also require matching names. + +```rust +use scylla::macros::{FromUserType, SerializeCql}; + +// Define a custom struct that matches the User Defined Type created earlier. +// Fields must be in the same order as they are in the database and also +// have the same names. +// Wrapping a field in Option will gracefully handle null field values. +#[derive(Debug, FromUserType, SerializeCql)] +struct MyType { + int_val: i32, + text_val: Option, +} +``` + +> ***Important***\ +> For deserialization, fields in the Rust struct must be defined in the same order as they are in the database. +> When receiving values, the driver will (de)serialize fields one after another, without looking at field names. + +> ***Important***\ +> For serialization, by default fields in the Rust struct must be defined with the same names as they are in the database. +> The driver will serialize the fields in the order defined by the UDT, matching Rust fields by name. +> You can change this behaviour using macro attributes, see `SerializeCql` macro documentation for more information. + +Now it can be sent and received just like any other CQL value: +```rust +use scylla::IntoTypedRows; +use scylla::macros::{FromUserType, SerializeCql}; +use scylla::cql_to_rust::FromCqlVal; + +#[derive(Debug, FromUserType, SerializeCql)] +struct MyType { + int_val: i32, + text_val: Option, +} + +// Insert my_type into the table +let to_insert = MyType { + int_val: 17, + text_val: Some("Some string".to_string()), +}; + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read MyType from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(MyType,)>() { + let (my_type_value,): (MyType,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/uuid.md.txt b/v0.12.0/_sources/data-types/uuid.md.txt new file mode 100644 index 0000000000..c4daa772cd --- /dev/null +++ b/v0.12.0/_sources/data-types/uuid.md.txt @@ -0,0 +1,21 @@ +# Uuid + +`Uuid` is represented as `uuid::Uuid`. + +```rust +use scylla::IntoTypedRows; +use uuid::Uuid; + +// Insert some uuid into the table +let to_insert: Uuid = Uuid::parse_str("8e14e760-7fa8-11eb-bc66-000000000001")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read uuid from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(Uuid,)>() { + let (uuid_value,): (Uuid,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/data-types/varint.md.txt b/v0.12.0/_sources/data-types/varint.md.txt new file mode 100644 index 0000000000..7c3f2317bf --- /dev/null +++ b/v0.12.0/_sources/data-types/varint.md.txt @@ -0,0 +1,32 @@ +# Varint +`Varint` is represented as `value::CqlVarint` or [`num_bigint::BigInt`](https://docs.rs/num-bigint/0.4.0/num_bigint/struct.BigInt.html). + +## num_bigint::BigInt + +To make use of `num_bigint::BigInt` type, user should enable one of the available feature flags (`num-bigint-03` or `num-bigint-04`). They enable support for `num_bigint::BigInt` v0.3 and v0.4 accordingly. + +## value::CqlVarint + +Without any feature flags, the user can interact with `Varint` type by making use of `value::CqlVarint` which +is a very simple wrapper representing the value as signed binary number in big-endian order. + +## Example + +```rust +use scylla::IntoTypedRows; +use num_bigint::BigInt; +use std::str::FromStr; + +// Insert a varint into the table +let to_insert: BigInt = BigInt::from_str("12345")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a varint from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(BigInt,)>() { + let (varint_value,): (BigInt,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.12.0/_sources/execution-profiles/create-and-use.md.txt b/v0.12.0/_sources/execution-profiles/create-and-use.md.txt new file mode 100644 index 0000000000..e33d5d2a26 --- /dev/null +++ b/v0.12.0/_sources/execution-profiles/create-and-use.md.txt @@ -0,0 +1,61 @@ +# Creating a profile and setting it + +### Example +To create an `ExecutionProfile` and attach it as default for `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::LocalOne) + .request_timeout(None) // no request timeout + .build(); + +let handle = profile.into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +### Example +To create an `ExecutionProfile` and attach it to a `Query`: +```rust +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::All) + .request_timeout(Some(Duration::from_secs(30))) + .build(); + +let handle = profile.into_handle(); + +let mut query1 = Query::from("SELECT * FROM ks.table"); +query1.set_execution_profile_handle(Some(handle.clone())); + +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?"); +query2.set_execution_profile_handle(Some(handle)); +``` + +### Example +To create an `ExecutionProfile` based on another profile: +```rust +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let base_profile = ExecutionProfile::builder() + .request_timeout(Some(Duration::from_secs(30))) + .build(); + +let profile = base_profile.to_builder() + .consistency(Consistency::All) + .build(); + +``` \ No newline at end of file diff --git a/v0.12.0/_sources/execution-profiles/execution-profiles.md.txt b/v0.12.0/_sources/execution-profiles/execution-profiles.md.txt new file mode 100644 index 0000000000..6f36726aff --- /dev/null +++ b/v0.12.0/_sources/execution-profiles/execution-profiles.md.txt @@ -0,0 +1,26 @@ +# Execution profiles + +Execution profiles are a way to group various query execution configuration options together. Profiles can be created to represent different workloads, which can be run conveniently on a single session. + +The settings that an execution profile encapsulates are [as follows](maximal-example.md): +* consistency +* serial consistency +* request timeout +* load balancing policy +* retry policy +* speculative execution policy + +There are two classes of objects related to execution profiles: `ExecutionProfile` and `ExecutionProfileHandle`. The former is simply an immutable set of the settings. The latter is a handle that at particular moment points to some `ExecutionProfile` (but during its lifetime, it can change the profile it points at). Handles are assigned to `Sessions` and `Statements`.\ +\ +At any moment, handles [can be remapped](remap.md) to point to another `ExecutionProfile`. This allows convenient switching between workloads for all `Sessions` and/or `Statements` that, for instance, share common characteristics. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + create-and-use + maximal-example + priority + remap +``` \ No newline at end of file diff --git a/v0.12.0/_sources/execution-profiles/maximal-example.md.txt b/v0.12.0/_sources/execution-profiles/maximal-example.md.txt new file mode 100644 index 0000000000..b784786574 --- /dev/null +++ b/v0.12.0/_sources/execution-profiles/maximal-example.md.txt @@ -0,0 +1,35 @@ +# All options supported by a profile + +### Example +`ExecutionProfile` supports all the following options: +```rust +use scylla::query::Query; +use scylla::speculative_execution::SimpleSpeculativeExecutionPolicy; +use scylla::statement::{Consistency, SerialConsistency}; +use scylla::transport::ExecutionProfile; +use scylla::transport::load_balancing::DefaultPolicy; +use scylla::transport::retry_policy::FallthroughRetryPolicy; +use std::{sync::Arc, time::Duration}; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::All) + .serial_consistency(Some(SerialConsistency::Serial)) + .request_timeout(Some(Duration::from_secs(30))) + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .load_balancing_policy(Arc::new(DefaultPolicy::default())) + .speculative_execution_policy( + Some( + Arc::new( + SimpleSpeculativeExecutionPolicy { + max_retry_count: 3, + retry_interval: Duration::from_millis(100), + } + ) + ) + ) + .build(); + +let mut query = Query::from("SELECT * FROM ks.table"); +query.set_execution_profile_handle(Some(profile.into_handle())); + +``` \ No newline at end of file diff --git a/v0.12.0/_sources/execution-profiles/priority.md.txt b/v0.12.0/_sources/execution-profiles/priority.md.txt new file mode 100644 index 0000000000..246c90fa24 --- /dev/null +++ b/v0.12.0/_sources/execution-profiles/priority.md.txt @@ -0,0 +1,48 @@ +# Priorities of execution settings + +You always have a default execution profile set for the `Session`, either the default one or overridden upon `Session` creation. Moreover, you can set a profile for specific statements, in which case the statement's profile has higher priority. Some options are also available for specific statements to be set directly on them, such as request timeout and consistency. In such case, the directly set options are preferred over those specified in execution profiles. + +> **Recap**\ +> Priorities are as follows:\ +> `Session`'s default profile < Statement's profile < options set directly on a Statement + + +### Example +Priorities of execution profiles and directly set options: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let session_profile = ExecutionProfile::builder() + .consistency(Consistency::One) + .build(); + +let query_profile = ExecutionProfile::builder() + .consistency(Consistency::Two) + .build(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(session_profile.into_handle()) + .build() + .await?; + +let mut query = Query::from("SELECT * FROM ks.table"); + +// Query is not assigned any specific profile, so session's profile is applied. +// Therefore, the query will be executed with Consistency::One. +session.query(query.clone(), ()).await?; + +query.set_execution_profile_handle(Some(query_profile.into_handle())); +// Query's profile is applied. +// Therefore, the query will be executed with Consistency::Two. +session.query(query.clone(), ()).await?; + +query.set_consistency(Consistency::Three); +// An option is set directly on the query. +// Therefore, the query will be executed with Consistency::Three. +session.query(query, ()).await?; + +``` \ No newline at end of file diff --git a/v0.12.0/_sources/execution-profiles/remap.md.txt b/v0.12.0/_sources/execution-profiles/remap.md.txt new file mode 100644 index 0000000000..470ebaefe7 --- /dev/null +++ b/v0.12.0/_sources/execution-profiles/remap.md.txt @@ -0,0 +1,69 @@ +# Remapping execution profile handles + +`ExecutionProfileHandle`s can be remapped to another `ExecutionProfile`, and the change affects all sessions and statements that have been assigned that handle. This enables quick workload switches. + +Example mapping: +* session1 -> handle1 -> profile1 +* statement1 -> handle1 -> profile1 +* statement2 -> handle2 -> profile2 + +We can now remap handle2 to profile1, so that the mapping for statement2 becomes as follows: +* statement2 -> handle2 -> profile1 + +We can also change statement1's handle to handle2, and remap handle1 to profile2, yielding: +* session1 -> handle1 -> profile2 +* statement1 -> handle2 -> profile1 +* statement2 -> handle2 -> profile1 + +As you can see, profiles are a powerful and convenient way to define and modify your workloads. + +### Example +Below, the remaps described above are followed in code. +```rust +use scylla::{Session, SessionBuilder}; +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let profile1 = ExecutionProfile::builder() + .consistency(Consistency::One) + .build(); + +let profile2 = ExecutionProfile::builder() + .consistency(Consistency::Two) + .build(); + +let mut handle1 = profile1.clone().into_handle(); +let mut handle2 = profile2.clone().into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle1.clone()) + .build() + .await?; + +let mut query1 = Query::from("SELECT * FROM ks.table"); +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?"); + +query1.set_execution_profile_handle(Some(handle1.clone())); +query2.set_execution_profile_handle(Some(handle2.clone())); + +// session1 -> handle1 -> profile1 +// query1 -> handle1 -> profile1 +// query2 -> handle2 -> profile2 + +// We can now remap handle2 to profile1: +handle2.map_to_another_profile(profile1); +// ...so that the mapping for query2 becomes as follows: +// query2 -> handle2 -> profile1 + +// We can also change query1's handle to handle2: +query1.set_execution_profile_handle(Some(handle2.clone())); +// ...and remap handle1 to profile2: +handle1.map_to_another_profile(profile2); +// ...yielding: +// session1 -> handle1 -> profile2 +// query1 -> handle2 -> profile1 +// query2 -> handle2 -> profile1 + +``` \ No newline at end of file diff --git a/v0.12.0/_sources/index.md.txt b/v0.12.0/_sources/index.md.txt new file mode 100644 index 0000000000..d2a6b79313 --- /dev/null +++ b/v0.12.0/_sources/index.md.txt @@ -0,0 +1,26 @@ +# Scylla Rust Driver +This book contains documentation for [scylla-rust-driver](https://github.com/scylladb/scylla-rust-driver) - a driver +for the [Scylla](https://scylladb.com) database written in Rust. +Although optimized for Scylla, the driver is also compatible with [Apache Cassandra®](https://cassandra.apache.org/). + +### Other documentation +* [Examples](https://github.com/scylladb/scylla-rust-driver/tree/main/examples) +* [Rust and Scylla lesson](https://university.scylladb.com/courses/using-scylla-drivers/lessons/rust-and-scylla-2/) on Scylla University +* [API documentation](https://docs.rs/scylla) +* [Scylla documentation](https://docs.scylladb.com) +* [Cassandra® documentation](https://cassandra.apache.org/doc/latest/) + + +## Contents +* [Quick start](quickstart/quickstart.md) - Setting up a Rust project using `scylla-rust-driver` and running a few queries +* [Migration guides](migration-guides/migration-guides.md) - How to update the code that used an older version of this driver +* [Connecting to the cluster](connecting/connecting.md) - Configuring a connection to scylla cluster +* [Making queries](queries/queries.md) - Making different types of queries (simple, prepared, batch, paged) +* [Execution profiles](execution-profiles/execution-profiles.md) - Grouping query execution configuration options together and switching them all at once +* [Data Types](data-types/data-types.md) - How to use various column data types +* [Load balancing](load-balancing/load-balancing.md) - Load balancing configuration +* [Retry policy configuration](retry-policy/retry-policy.md) - What to do when a query fails, query idempotence +* [Driver metrics](metrics/metrics.md) - Statistics about the driver - number of queries, latency etc. +* [Logging](logging/logging.md) - Viewing and integrating logs produced by the driver +* [Query tracing](tracing/tracing.md) - Tracing query execution +* [Database schema](schema/schema.md) - Fetching and inspecting database schema diff --git a/v0.12.0/_sources/load-balancing/default-policy.md.txt b/v0.12.0/_sources/load-balancing/default-policy.md.txt new file mode 100644 index 0000000000..c1ad0ee2bf --- /dev/null +++ b/v0.12.0/_sources/load-balancing/default-policy.md.txt @@ -0,0 +1,167 @@ +# DefaultPolicy + +`DefaultPolicy` is the default load balancing policy in Scylla Rust Driver. It +can be configured to be datacenter-aware and token-aware. Datacenter failover +for queries with non-local consistency mode is also supported. + +## Creating a DefaultPolicy + +`DefaultPolicy` can be created only using `DefaultPolicyBuilder`. The +`builder()` method of `DefaultPolicy` returns a new instance of +`DefaultPolicyBuilder` with the following default values: + +- `preferences`: no particular datacenter/rack preference +- `is_token_aware`: `true` +- `permit_dc_failover`: `false` +- `latency_awareness`: `None` + +You can use the builder methods to configure the desired settings and create a +`DefaultPolicy` instance: + +```rust +use scylla::load_balancing::DefaultPolicy; + +let default_policy = DefaultPolicy::builder() + .prefer_datacenter_and_rack("dc1".to_string(), "rack1".to_string()) + .token_aware(true) + .permit_dc_failover(true) + .build(); +``` + +### Semantics of `DefaultPolicy` + +#### Preferences + +The `preferences` field in `DefaultPolicy` allows the load balancing +policy to prioritize nodes based on their location. It has three modes: + +- no preference +- preferred datacenter +- preferred datacenter and rack + +When a datacenter `"my_dc"` is preferred, the policy will treat nodes in `"my_dc"` +as "local" nodes, and nodes in other datacenters as "remote" nodes. This affects +the order in which nodes are returned by the policy when selecting nodes for +read or write operations. If no datacenter is preferred, the policy will treat +all nodes as local nodes. + +`preferences` allow the load balancing policy to prioritize nodes based on their +availability zones (racks) in the preferred datacenter, too. When a datacenter +and a rack are preferred, the policy will first return replicas in the local rack +in the preferred datacenter, and then the other replicas in the datacenter +(followed by remote replicas). After replicas, the other node will be ordered +similarly, too (local rack nodes, local datacenter nodes, remote nodes). + +When datacenter failover is disabled (`permit_dc_failover` is set to +false), the default policy will only include local nodes in load balancing +plans. Remote nodes will be excluded, even if they are alive and available to +serve requests. + +#### Datacenter Failover + +In the event of a datacenter outage or network failure, the nodes in that +datacenter may become unavailable, and clients may no longer be able to access +the data stored on those nodes. To address this, the `DefaultPolicy` supports +datacenter failover, which allows to route requests to nodes in other datacenters +if the local nodes are unavailable. + +Datacenter failover can be enabled in `DefaultPolicy` by `permit_dc_failover` +setting in the builder. When this flag is set, the policy will prefer to return +alive remote replicas if datacenter failover is permitted and possible due to +consistency constraints. + +#### Token awareness + +Token awareness refers to a mechanism by which the driver is aware of the token +range assigned to each node in the cluster. Tokens are assigned to nodes to +partition the data and distribute it across the cluster. + +When a user wants to read or write data, the driver can use token awareness to +route the request to the correct node based on the token range of the data +being accessed. This can help to minimize network traffic and improve +performance by ensuring that the data is accessed locally as much as possible. + +In the case of `DefaultPolicy`, token awareness is enabled by default, meaning +that the policy will prefer to return alive local replicas if the token is +available. This means that if the client is requesting data that falls within +the token range of a particular node, the policy will try to route the request +to that node first, assuming it is alive and responsive. + +Token awareness can significantly improve the performance and scalability of +applications built on Scylla. By using token awareness, users can ensure that +data is accessed locally as much as possible, reducing network overhead and +improving throughput. + +Please note that for token awareness to be applied, a statement must be +prepared before being executed. + +### Latency awareness + +Latency awareness is a mechanism that penalises nodes whose measured recent +average latency classifies it as falling behind the others. + +Every `update_rate` the global minimum average latency is computed, +and all nodes whose average latency is worse than `exclusion_threshold` +times the global minimum average latency become penalised for +`retry_period`. Penalisation involves putting those nodes at the very end +of the query plan. As it is often not truly beneficial to prefer +faster non-replica than replicas lagging behind the non-replicas, +this mechanism may as well worsen latencies and/or throughput. + +> **Warning** +> +> Using latency awareness is **NOT** recommended, unless prior +>benchmarks prove its beneficial impact on the specific workload's +>performance. Use with caution. + +### Creating a latency aware DefaultPolicy + +```rust +use scylla::load_balancing::{ + LatencyAwarenessBuilder, DefaultPolicy +}; +use std::time::Duration; + +let latency_awareness_builder = LatencyAwarenessBuilder::new() + .exclusion_threshold(3.) + .update_rate(Duration::from_secs(3)) + .retry_period(Duration::from_secs(30)) + .minimum_measurements(200); + +let policy = DefaultPolicy::builder() + // Here further customisation is, of course, possible. + // e.g.: .prefer_datacenter(...) + .latency_awareness(latency_awareness_builder) + .build(); +``` + +```rust +use scylla::load_balancing::DefaultPolicy; + +let default_policy = DefaultPolicy::builder() + .prefer_datacenter("dc1".to_string()) + .token_aware(true) + .permit_dc_failover(true) + .build(); +``` + +### Node order in produced plans + +The DefaultPolicy prefers to return nodes in the following order: + +1. Alive local replicas (if token is available & token awareness is enabled) +2. Alive remote replicas (if datacenter failover is permitted & possible due to consistency constraints) +3. Alive local nodes +4. Alive remote nodes (if datacenter failover is permitted & possible due to consistency constraints) +5. Enabled down nodes +And only if latency awareness is enabled: +6. Penalised: alive local replicas, alive remote replicas, ... (in order as above). + +If no preferred datacenter is specified, all nodes are treated as local ones. + +Replicas in the same priority groups are shuffled[^1]. Non-replicas are randomly +rotated (similarly to a round robin with a random index). + +[^1]: There is an optimisation implemented for LWT requests that routes them +to the replicas in the ring order (as it prevents contention due to Paxos conflicts), so replicas in that case are not shuffled in groups at all. +In order for the optimisation to be applied, LWT statements must be prepared before. diff --git a/v0.12.0/_sources/load-balancing/load-balancing.md.txt b/v0.12.0/_sources/load-balancing/load-balancing.md.txt new file mode 100644 index 0000000000..3a9c102afa --- /dev/null +++ b/v0.12.0/_sources/load-balancing/load-balancing.md.txt @@ -0,0 +1,119 @@ +# Load balancing + +## Introduction + +The driver uses a load balancing policy to determine which node(s) to contact +when executing a query. Load balancing policies implement the +`LoadBalancingPolicy` trait, which contains methods to generate a load +balancing plan based on the query information and the state of the cluster. + +Load balancing policies do not influence to which nodes connections are +being opened. For a node connection blacklist configuration refer to +`scylla::transport::host_filter::HostFilter`, which can be set session-wide +using `SessionBuilder::host_filter` method. + +## Plan + +When a query is prepared to be sent to the database, the load balancing policy +constructs a load balancing plan. This plan is essentially a list of nodes to +which the driver will try to send the query. The first elements of the plan are +the nodes which are the best to contact (e.g. they might be replicas for the +requested data or have the best latency). + +## Policy + +The Scylla/Cassandra driver provides a default load balancing policy (see +[Default Policy](default-policy.md) for details), but you can +also implement your own custom policies that better suit your specific use +case. To use a custom policy, you simply need to implement the +`LoadBalancingPolicy` trait and pass an instance of your custom policy to the +used execution profile. + +Our recommendation is to use [`Default Policy`](default-policy.md) with token- +awareness enabled and latency-awareness disabled. + +## Configuration + +Load balancing policies can be configured via execution profiles. In the code +sample provided, a new execution profile is created using +`ExecutionProfile::builder()`, and the load balancing policy is set to the +`DefaultPolicy` using `.load_balancing_policy(policy)`. + +The newly created execution profile is then converted to a handle using +`.into_handle()`, and passed as the default execution profile to the +`SessionBuilder` using `.default_execution_profile_handle(handle)`. + +```rust +use scylla::SessionBuilder; +use scylla::load_balancing::DefaultPolicy; +use scylla::transport::ExecutionProfile; +use scylla::transport::session::Session; +use std::sync::Arc; + +let policy = Arc::new(DefaultPolicy::default()); + +let profile = ExecutionProfile::builder() + .load_balancing_policy(policy) + .build(); +let handle = profile.into_handle(); + +let session: Session = SessionBuilder::new() + .known_node(&uri) + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +In addition to being able to configure load balancing policies through +execution profiles at the session level, the driver also allow for setting +execution profile handles on a per-query basis. This means that for each query, +a specific execution profile can be selected with a customized load balancing +settings. + +## `LoadBalancingPolicy` trait + +### `pick` and `fallback`: + +Most queries are sent successfully on the first try. In such cases, only the +first element of the load balancing plan is needed, so it's usually unnecessary +to compute entire load balancing plan. To optimize this common case, the +`LoadBalancingPolicy` trait provides two methods: `pick` and `fallback`. + +`pick` returns the first node to contact for a given query, which is usually +the best based on a particular load balancing policy. If `pick` returns `None`, +then `fallback` will not be called. + +`fallback`, returns an iterator that provides the rest of the nodes in the load +balancing plan. `fallback` is called only when using the initial picked node +fails (or when executing speculatively). + +It's possible for the `fallback` method to include the same node that was +returned by the `pick` method. In such cases, the query execution layer filters +out the picked node from the iterator returned by `fallback`. + +### `on_query_success` and `on_query_failure`: + +The `on_query_success` and `on_query_failure` methods are useful for load +balancing policies because they provide feedback on the performance and health +of the nodes in the cluster. + +When a query is successfully executed, the `on_query_success` method is called +and can be used by the load balancing policy to update its internal state. For +example, a policy might use the latency of the successful query to update its +latency statistics for each node in the cluster. This information can be used +to make decisions about which nodes to contact in the future. + +On the other hand, when a query fails to execute, the `on_query_failure` method +is called and provides information about the failure. The error message +returned by Cassandra can help determine the cause of the failure, such as a +node being down or overloaded. The load balancing policy can use this +information to update its internal state and avoid contacting the same node +again until it's recovered. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + default-policy +``` diff --git a/v0.12.0/_sources/logging/logging.md.txt b/v0.12.0/_sources/logging/logging.md.txt new file mode 100644 index 0000000000..5b129f4cdc --- /dev/null +++ b/v0.12.0/_sources/logging/logging.md.txt @@ -0,0 +1,42 @@ +# Logging + +The driver uses the [tracing](https://github.com/tokio-rs/tracing) crate for all logs.\ +To view the logs you have to create a `tracing` subscriber to which all logs will be written. + +To just print the logs you can use the default subscriber: +```rust +use tracing::info; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Install global collector configured based on RUST_LOG env var + // This collector will receive logs from the driver + tracing_subscriber::fmt::init(); + + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + info!("Connecting to {}", uri); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + session + .query( + "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \ + {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}", + &[], + ) + .await?; + + // This query should generate a warning message + session.query("USE ks", &[]).await?; + + Ok(()) +} +``` + +To start this example execute: +```shell +RUST_LOG=info cargo run +``` + +The full [example](https://github.com/scylladb/scylla-rust-driver/tree/main/examples/logging.rs) is available in the `examples` folder \ No newline at end of file diff --git a/v0.12.0/_sources/metrics/metrics.md.txt b/v0.12.0/_sources/metrics/metrics.md.txt new file mode 100644 index 0000000000..7fb831a504 --- /dev/null +++ b/v0.12.0/_sources/metrics/metrics.md.txt @@ -0,0 +1,28 @@ +# Driver metrics + +During operation the driver collects various metrics. + +They can be accessed at any moment using `Session::get_metrics()` + +### Collected metrics: +* Query latencies +* Total number of nonpaged queries +* Number of errors during nonpaged queries +* Total number of paged queries +* Number of errors during paged queries +* Number of retries + +### Example +```rust +let metrics = session.get_metrics(); + +println!("Queries requested: {}", metrics.get_queries_num()); +println!("Iter queries requested: {}", metrics.get_queries_iter_num()); +println!("Errors occurred: {}", metrics.get_errors_num()); +println!("Iter errors occurred: {}", metrics.get_errors_iter_num()); +println!("Average latency: {}", metrics.get_latency_avg_ms().unwrap()); +println!( + "99.9 latency percentile: {}", + metrics.get_latency_percentile_ms(99.9).unwrap() +); +``` \ No newline at end of file diff --git a/v0.12.0/_sources/migration-guides/0.11-serialization.md.txt b/v0.12.0/_sources/migration-guides/0.11-serialization.md.txt new file mode 100644 index 0000000000..429a0168cf --- /dev/null +++ b/v0.12.0/_sources/migration-guides/0.11-serialization.md.txt @@ -0,0 +1,101 @@ +# Adjusting code to changes in serialization API introduced in 0.11 + +## Background + +When executing a statement through the CQL protocol, values for the bind markers are sent in a serialized, untyped form. In order to implement a safer and more robust interface, drivers can use the information returned after preparing a statement to check the type of data provided by the user against the actual types of the bind markers. + +Before 0.11, the driver couldn't do this kind of type checking. For example, in the case of non-batch queries, the only information about the user data it has is that it implements `ValueList` - defined as follows: + +```rust + +pub trait ValueList { + fn serialized(&self) -> SerializedResult<'_>; + fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError>; +} +``` + +The driver would naively serialize the data and hope that the user took care to send correct types of values. Failing to do so would, in the best case, fail on the DB-side validation; in the worst case, the data in its raw form may be reinterpreted as another type in an unintended manner. + +Another problem is that the information from the prepared statement response is required to robustly serialize user defined types, as UDTs require their fields to be serialized in the same order as they are defined in the database schema. The `IntoUserType` macro which implements Rust struct -> UDT serialization just expects that the order of the Rust struct fields matches the schema, but ensuring this can be very cumbersome for the users. + +In version 0.11, a new set of traits is introduced and the old ones are deprecated. The new traits receive more information during serialization such as names of the column/bind markers and their types, which allows to fix the issues mentioned in the previous section. + +## Old vs. new + +Both the old and the new APIs are based on three core traits: + +- `Value` - called `SerializeCql` in the new API. A type that can serialize itself to a single CQL value. For example, `i32` serializes itself into a representation that is compatible with the CQL `int` type. +- `ValueList` - called `SerializeRow` in the new API. A type that can serialize itself as a list of values for a CQL statement. For example, a `(i32, &str)` produces a list of two values which can be used in a query with two bind markers, e.g. `SELECT * FROM table WHERE pk = ? AND ck = ?`. Optionally, values in the produced list may be associated with names which is useful when using it with a query with named bind markers, e.g. `SELECT * FROM table WHERE pk = :pk AND ck = :ck`. +- `LegacyBatchValues`, previously named `BatchValues` - in new API replaced with new trait called (again) `BatchValues`. Represents a source of data for a batch request. It is essentially equivalent to a list of `ValueList`, one for each statement in the batch. For example, `((1, 2), (3, 4, 5))` can be used for a batch with two statements, the first one having two bind markers and the second one having three. + +All methods which take one of the old traits were changed to take the new trait - notably, this includes `Session::query`, `(Caching)Session::execute`, `(Caching)Session::batch`. + +The driver comes a set of `impl`s of those traits which allow to represent any CQL type (for example, see [Data Types](../data-types/data-types.md) page for a list of for which `Value` and `SerializeCql` is implemented). If the driver implements an old trait for some type, then it also provides implements the new trait for the same type. + +## Migration scenarios + +### Different default behavior in `SerializeRow`/`SerializeCql` macros + +By default, the `SerializeRow` and `SerializeCql` **will match the fields in the Rust struct by name to bind marker names** (in case of `SerializeRow`) **or UDT field names** (in case of `SerializeCql`). This is different from the old `ValueList` and `IntoUserType` macros which did not look at the field names at all and would expect the user to order the fields correctly. While the new behavior is much more ergonomic, you might have reasons not to use it. + +> **NOTE:** The deserialization macro counterparts `FromRow` and `FromUserType` have the same limitation as the old serialization macros - they require struct fields to be properly ordered. While a similar rework is planned for the deserialization traits in a future release, for the time being it might not be worth keeping the column names in sync with the database. + +In order to bring the old behavior to the new macros (the only difference being type checking which cannot be disabled right now) you can configure it using attributes, as shown in the snippet below: + +```rust +use scylla::SerializeCql; + +// The exact same attributes apply to the `SerializeRow` macro and their +// effect is completely analogous. +#[derive(SerializeCql)] +#[scylla(flavor = "enforce_order", skip_name_checks)] +struct Person { + name: String, + surname: String, + age: i16, +} +``` + +Refer to the API reference page for the `SerializeRow` and `SerializeCql` macros in the `scylla` crate to learn more about the supported attributes and their meaning. + +### Preparing is mandatory with a non-empty list of values + +> **NOTE:** The considerations in this section only concerns users of the `Session` API, `CachingSession` is not affected as it already does preparation before execute and caches the result. + +As explained in the [Background](#background) section, the driver uses data returned from the database after preparing a statement in order to implement type checking. As the new API makes type checking mandatory, **the driver must prepare the statement** so that the data for the bind markers can be type checked. It is done in case of the existing methods which used to send unprepared statements: `Session::query` and `Session::batch`. + +> **NOTE:** The driver will skip preparation if it detects that the list of values for the statement is empty, as there is nothing to be type checked. + +If you send simple statements along with non-empty lists of values, the slowdown will be as follows: + +- For `Session::query`, the driver will prepare the statement before sending it, incurring an additional round-trip. +- For `Session::batch`, the driver will send a prepare request for each *unique* unprepared statement with a non-empty list of values. **This is done serially!** + +In both cases, if the additional roundtrips are unacceptable, you should prepare the statements beforehand and reuse them - which aligns with our general recommendation against use of simple statements in performance sensitive scenarios. + +### Migrating from old to new traits *gradually* + +In some cases, migration will be as easy as changing occurrences of `IntoUserType` to `SerializeCql` and `ValueList` to `SerializeRow` and adding some atributes for procedural macros. However, if you have a large enough codebase or some custom, complicated implementations of the old traits then you might not want to migrate everything at once. To support gradual migration, the old traits were not removed but rather deprecated, and we introduced some additional utilities. + +#### Converting an object implementing an old trait to a new trait + +We provide a number of newtype wrappers: + +- `ValueAdapter` - implements `SerializeCql` if the type wrapped over implements `Value`, +- `ValueListAdapter` - implements `SerializeRow` if the type wrapped over implements `ValueList`, +- `LegacyBatchValuesAdapter` - implements `BatchValues` if the type wrapped over implements `LegacyBatchValues`. + +Note that these wrappers are not zero cost and incur some overhead: in case of `ValueAdapter` and `ValueListAdapter`, the data is first written into a newly allocated buffer and then rewritten to the final buffer. In case of `LegacyBatchValuesAdapter` there shouldn't be any additional allocations unless the implementation has an efficient, non-default `Self::LegacyBatchValuesIterator::write_next_to_request` implementation (which is not the case for the built-in `impl`s). + +Naturally, the implementations provided by the wrappers are not type safe as they directly use methods from the old traits. + +Conversion in the other direction is not possible. + +#### Custom implementations of old traits + +It is possible to directly generate an `impl` of `SerializeRow` and `SerializeCql` on a type which implements, respectively, `ValueList` or `Value`, without using the wrappers from the previous section. The following macros are provided: + +- `impl_serialize_cql_via_value` - implements `SerializeCql` if the type wrapped over implements `Value`, +- `impl_serialize_row_via_value_list` - implements `SerializeRow` if the type wrapped over implements `ValueList`, + +The implementations are practically as those generated by the wrappers described in the previous section. diff --git a/v0.12.0/_sources/migration-guides/migration-guides.md.txt b/v0.12.0/_sources/migration-guides/migration-guides.md.txt new file mode 100644 index 0000000000..86887a64c9 --- /dev/null +++ b/v0.12.0/_sources/migration-guides/migration-guides.md.txt @@ -0,0 +1,11 @@ +# Migration guides + +- [Serialization changes in version 0.11](0.11-serialization.md) + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + 0.11-serialization +``` diff --git a/v0.12.0/_sources/queries/batch.md.txt b/v0.12.0/_sources/queries/batch.md.txt new file mode 100644 index 0000000000..271c96baa1 --- /dev/null +++ b/v0.12.0/_sources/queries/batch.md.txt @@ -0,0 +1,127 @@ +# Batch statement + +A batch statement allows to execute many data-modifying statements at once.\ +These statements can be [simple](simple.md) or [prepared](prepared.md).\ +Only `INSERT`, `UPDATE` and `DELETE` statements are allowed. + +```rust +use scylla::batch::Batch; +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; + +// Create a batch statement +let mut batch: Batch = Default::default(); + +// Add a simple statement to the batch using its text +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(1, 2)"); + +// Add a simple statement created manually to the batch +let simple: Query = Query::new("INSERT INTO ks.tab (a, b) VALUES(3, 4)"); +batch.append_statement(simple); + +// Add a prepared statement to the batch +let prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a, b) VALUES(?, 6)") + .await?; +batch.append_statement(prepared); + +// Specify bound values to use with each statement +let batch_values = ((), + (), + (5_i32,)); + +// Run the batch +session.batch(&batch, batch_values).await?; +``` + +> ***Warning***\ +> Using simple statements with bind markers in batches is strongly discouraged. +> For each simple statement with a non-empty list of values in the batch, +> the driver will send a prepare request, and it will be done **sequentially**. +> Results of preparation are not cached between `Session::batch` calls. +> Consider preparing the statements before putting them into the batch. + +### Preparing a batch +Instead of preparing each statement individually, it's possible to prepare a whole batch at once: + +```rust +use scylla::batch::Batch; + +// Create a batch statement with unprepared statements +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.simple_unprepared1 VALUES(?, ?)"); +batch.append_statement("INSERT INTO ks.simple_unprepared2 VALUES(?, ?)"); + +// Prepare all statements in the batch at once +let prepared_batch: Batch = session.prepare_batch(&batch).await?; + +// Specify bound values to use with each statement +let batch_values = ((1_i32, 2_i32), + (3_i32, 4_i32)); + +// Run the prepared batch +session.batch(&prepared_batch, batch_values).await?; +``` + +### Batch options +You can set various options by operating on the `Batch` object.\ +For example to change consistency: +```rust +use scylla::batch::Batch; +use scylla::statement::Consistency; + +// Create a batch +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.tab(a) VALUES(16)"); + +// Set batch consistency to One +batch.set_consistency(Consistency::One); + +// Run the batch +session.batch(&batch, ((), )).await?; +``` + +See [Batch API documentation](https://docs.rs/scylla/latest/scylla/statement/batch/struct.Batch.html) +for more options + +### Batch values +Batch takes a tuple of values specified just like in [simple](simple.md) or [prepared](prepared.md) queries. + +Length of batch values must be equal to the number of statements in a batch.\ +Each statement must have its values specified, even if they are empty. + +Values passed to `Session::batch` must implement the trait `BatchValues`.\ +By default this includes tuples `()` and slices `&[]` of tuples and slices which implement `ValueList`. + +Example: +```rust +use scylla::batch::Batch; + +let mut batch: Batch = Default::default(); + +// A statement with two bound values +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(?, ?)"); + +// A statement with one bound value +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(3, ?)"); + +// A statement with no bound values +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(5, 6)"); + +// Batch values is a tuple of 3 tuples containing values for each statement +let batch_values = ((1_i32, 2_i32), // Tuple with two values for the first statement + (4_i32,), // Tuple with one value for the second statement + ()); // Empty tuple/unit for the third statement + +// Run the batch +// Note that the driver will prepare the first two statements, due to them +// not being prepared and having a non-empty list of values. +session.batch(&batch, batch_values).await?; +``` +For more information about sending values in a statement see [Query values](values.md) + + +### Performance +Batch statements do not use token/shard aware load balancing, batches are sent to a random node. + +Use [prepared queries](prepared.md) for best performance diff --git a/v0.12.0/_sources/queries/lwt.md.txt b/v0.12.0/_sources/queries/lwt.md.txt new file mode 100644 index 0000000000..6efc0659c4 --- /dev/null +++ b/v0.12.0/_sources/queries/lwt.md.txt @@ -0,0 +1,26 @@ +# Lightweight transaction (LWT) query + +A lightweight transaction query can be expressed just like any other query, via `Session`, with the notable difference of having an additional consistency level parameter - the `serial_consistency_level`. + + +### Format of the query +A lightweight transaction query is not a separate type - it can be expressed just like any other queries: via `SimpleQuery`, `PreparedStatement`, batches, and so on. The difference lays in the query string itself - when it contains a condition (e.g. `IF NOT EXISTS`), it becomes a lightweight transaction. It's important to remember that CQL specification requires a separate, additional consistency level to be defined for LWT queries - `serial_consistency_level`. The serial consistency level can only be set to two values: `SerialConsistency::Serial` or `SerialConsistency::LocalSerial`. The "local" variant makes the transaction consistent only within the same datacenter. For convenience, Scylla Rust Driver sets the default consistency level to `LocalSerial`, as it's more commonly used. For cross-datacenter consistency, please remember to always override the default with `SerialConsistency::Serial`. +```rust +use scylla::query::Query; +use scylla::statement::{Consistency, SerialConsistency}; + +// Create a Query manually to change the Consistency to ONE +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?) IF NOT EXISTS".to_string()); +my_query.set_consistency(Consistency::One); +// Use cross-datacenter serial consistency +my_query.set_serial_consistency(Some(SerialConsistency::Serial)); + +// Insert a value into the table +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +The rest of the API remains identical for LWT and non-LWT queries. + +See [Query API documentation](https://docs.rs/scylla/latest/scylla/statement/query/struct.Query.html) for more options + diff --git a/v0.12.0/_sources/queries/paged.md.txt b/v0.12.0/_sources/queries/paged.md.txt new file mode 100644 index 0000000000..ce6173ac72 --- /dev/null +++ b/v0.12.0/_sources/queries/paged.md.txt @@ -0,0 +1,118 @@ +# Paged query +Sometimes query results might not fit in a single page. Paged queries +allow to receive the whole result page by page. + +`Session::query_iter` and `Session::execute_iter` take a [simple query](simple.md) or a [prepared query](prepared.md) +and return an `async` iterator over result `Rows`. + +> ***Warning***\ +> In case of unprepared variant (`Session::query_iter`) if the values are not empty +> driver will first fully prepare a query (which means issuing additional request to each +> node in a cluster). This will have a performance penalty - how big it is depends on +> the size of your cluster (more nodes - more requests) and the size of returned +> result (more returned pages - more amortized penalty). In any case, it is preferable to +> use `Session::execute_iter`. + +### Examples +Use `query_iter` to perform a [simple query](simple.md) with paging: +```rust +use scylla::IntoTypedRows; +use futures::stream::StreamExt; + +let mut rows_stream = session + .query_iter("SELECT a, b FROM ks.t", &[]) + .await? + .into_typed::<(i32, i32)>(); + +while let Some(next_row_res) = rows_stream.next().await { + let (a, b): (i32, i32) = next_row_res?; + println!("a, b: {}, {}", a, b); +} +``` + +Use `execute_iter` to perform a [prepared query](prepared.md) with paging: +```rust +use scylla::IntoTypedRows; +use scylla::prepared_statement::PreparedStatement; +use futures::stream::StreamExt; + +let prepared: PreparedStatement = session + .prepare("SELECT a, b FROM ks.t") + .await?; + +let mut rows_stream = session + .execute_iter(prepared, &[]) + .await? + .into_typed::<(i32, i32)>(); + +while let Some(next_row_res) = rows_stream.next().await { + let (a, b): (i32, i32) = next_row_res?; + println!("a, b: {}, {}", a, b); +} +``` + +Query values can be passed to `query_iter` and `execute_iter` just like in a [simple query](simple.md) + +### Configuring page size +It's possible to configure the size of a single page. + +On a `Query`: +```rust +use scylla::query::Query; + +let mut query: Query = Query::new("SELECT a, b FROM ks.t"); +query.set_page_size(16); + +let _ = session.query_iter(query, &[]).await?; // ... +``` + +On a `PreparedStatement`: +```rust +use scylla::prepared_statement::PreparedStatement; + +let mut prepared: PreparedStatement = session + .prepare("SELECT a, b FROM ks.t") + .await?; + +prepared.set_page_size(16); + +let _ = session.execute_iter(prepared, &[]).await?; // ... +``` + +### Passing the paging state manually +It's possible to fetch a single page from the table, extract the paging state +from the result and manually pass it to the next query. That way, the next +query will start fetching the results from where the previous one left off. + +On a `Query`: +```rust +use scylla::query::Query; + +let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6); +let res1 = session.query(paged_query.clone(), &[]).await?; +let res2 = session + .query_paged(paged_query.clone(), &[], res1.paging_state) + .await?; +``` + +> ***Warning***\ +> If the values are not empty, driver first needs to send a `PREPARE` request +> in order to fetch information required to serialize values. This will affect +> performance because 2 round trips will be required instead of 1. + +On a `PreparedStatement`: +```rust +use scylla::query::Query; + +let paged_prepared = session + .prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7)) + .await?; +let res1 = session.execute(&paged_prepared, &[]).await?; +let res2 = session + .execute_paged(&paged_prepared, &[], res1.paging_state) + .await?; +``` + +### Performance +Performance is the same as in non-paged variants.\ +For the best performance use [prepared queries](prepared.md). \ No newline at end of file diff --git a/v0.12.0/_sources/queries/prepared.md.txt b/v0.12.0/_sources/queries/prepared.md.txt new file mode 100644 index 0000000000..e4551a2ae8 --- /dev/null +++ b/v0.12.0/_sources/queries/prepared.md.txt @@ -0,0 +1,108 @@ +# Prepared query + +Prepared queries provide much better performance than simple queries, +but they need to be prepared before use. + +```rust +use scylla::prepared_statement::PreparedStatement; + +// Prepare the query for later execution +let prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +// Run the prepared query with some values, just like a simple query +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` + +> ***Warning***\ +> For token/shard aware load balancing to work properly, all partition key values +> must be sent as bound values (see [performance section](#performance)) + +> ***Warning***\ +> Don't use `execute` to receive large amounts of data.\ +> By default the query is unpaged and might cause heavy load on the cluster. +> In such cases set a page size and use a [paged query](paged.md) instead. +> +> When page size is set, `execute` will return only the first page of results. + +### `Session::prepare` +`Session::prepare` takes query text and prepares the query on all nodes and shards. +If at least one succeeds returns success. + +### `Session::execute` +`Session::execute` takes a prepared query and bound values and runs the query. +Passing values and the result is the same as in [simple query](simple.md). + +### Query options + +To specify custom options, set them on the `PreparedStatement` before execution. +For example to change the consistency: + +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::statement::Consistency; + +// Prepare the query for later execution +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +// Set prepared query consistency to One +// This is the consistency with which this query will be executed +prepared.set_consistency(Consistency::One); + +// Run the prepared query with some values, just like a simple query +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` + +See [PreparedStatement API documentation](https://docs.rs/scylla/latest/scylla/statement/prepared_statement/struct.PreparedStatement.html) +for more options. + +> ***Note*** +> Prepared statements can be created from `Query` structs and will inherit from +> the custom options that the `Query` was created with. +> This is especially useful when using `CachingSession::execute` for example. + +### Performance + +Prepared queries have good performance, much better than simple queries. +By default they use shard/token aware load balancing. + +> **Always** pass partition key values as bound values. +> Otherwise the driver can't hash them to compute partition key +> and they will be sent to the wrong node, which worsens performance. + +Let's say we have a table like this: + +```sql +TABLE ks.prepare_table ( + a int, + b int, + c int, + PRIMARY KEY (a, b) +) +``` + +```rust +use scylla::prepared_statement::PreparedStatement; + +// WRONG - partition key value is passed in query string +// Load balancing will compute the wrong partition key +let wrong_prepared: PreparedStatement = session + .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(12345, ?, 16)") + .await?; + +session.execute(&wrong_prepared, (54321,)).await?; + +// GOOD - partition key values are sent as bound values +// Other values can be sent any way you like, it doesn't matter +let good_prepared: PreparedStatement = session + .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(?, ?, 16)") + .await?; + +session.execute(&good_prepared, (12345, 54321)).await?; + +``` diff --git a/v0.12.0/_sources/queries/queries.md.txt b/v0.12.0/_sources/queries/queries.md.txt new file mode 100644 index 0000000000..b75810d0ad --- /dev/null +++ b/v0.12.0/_sources/queries/queries.md.txt @@ -0,0 +1,39 @@ +# Making queries + +This driver supports all query types available in Scylla: +* [Simple queries](simple.md) + * Easy to use + * Poor performance + * Primitive load balancing +* [Prepared queries](prepared.md) + * Need to be prepared before use + * Fast + * Properly load balanced +* [Batch statements](batch.md) + * Run multiple queries at once + * Can be prepared for better performance and load balancing +* [Paged queries](paged.md) + * Allows to read result in multiple pages when it doesn't fit in a single response + * Can be prepared for better performance and load balancing + +Additionally there is special functionality to enable `USE KEYSPACE` queries: +[USE keyspace](usekeyspace.md) + +Queries are fully asynchronous - you can run as many of them in parallel as you wish. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + simple + values + result + prepared + batch + paged + usekeyspace + schema-agreement + lwt + timeouts +``` diff --git a/v0.12.0/_sources/queries/result.md.txt b/v0.12.0/_sources/queries/result.md.txt new file mode 100644 index 0000000000..0374599301 --- /dev/null +++ b/v0.12.0/_sources/queries/result.md.txt @@ -0,0 +1,115 @@ +# Query result + +`Session::query` and `Session::execute` return a `QueryResult` with rows represented as `Option>`. + +### Basic representation +`Row` is a basic representation of a received row. It can be used by itself, but it's a bit awkward to use: +```rust +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows { + let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap(); + } +} +``` + +### Parsing using `into_typed` +The driver provides a way to parse a row as a tuple of Rust types: +```rust +use scylla::IntoTypedRows; + +// Parse row as a single column containing an int value +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows { + let (int_value,): (i32,) = row.into_typed::<(i32,)>()?; + } +} + +// rows.into_typed() converts a Vec of Rows to an iterator of parsing results +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32,)>() { + let (int_value,): (i32,) = row?; + } +} + +// Parse row as two columns containing an int and text columns +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32, String)>() { + let (int_value, text_value): (i32, String) = row?; + } +} +``` + +## Parsing using convenience methods +[`QueryResult`](https://docs.rs/scylla/latest/scylla/transport/query_result/struct.QueryResult.html) provides convenience methods for parsing rows. +Here are a few of them: +* `rows_typed::()` - returns the rows parsed as the given type +* `maybe_first_row_typed::` - returns `Option` containing first row from the result +* `first_row_typed::` - same as `maybe_first_row`, but fails without the first row +* `single_row_typed::` - same as `first_row`, but fails when there is more than one row +* `result_not_rows()` - ensures that query response was not `rows`, helps avoid bugs + + +```rust +// Parse row as a single column containing an int value +let rows = session + .query("SELECT a from ks.tab", &[]) + .await? + .rows_typed::<(i32,)>()?; // Same as .rows()?.into_typed() +for row in rows { + let (int_value,): (i32,) = row?; +} + +// maybe_first_row_typed gets the first row and parses it as the given type +let first_int_val: Option<(i32,)> = session + .query("SELECT a from ks.tab", &[]) + .await? + .maybe_first_row_typed::<(i32,)>()?; + +// no_rows fails when the response is rows +session.query("INSERT INTO ks.tab (a) VALUES (0)", &[]).await?.result_not_rows()?; +``` +For more see [`QueryResult`](https://docs.rs/scylla/latest/scylla/transport/query_result/struct.QueryResult.html) + +### `NULL` values +`NULL` values will return an error when parsed as a Rust type. +To properly handle `NULL` values parse column as an `Option<>`: +```rust +use scylla::IntoTypedRows; + +// Parse row as two columns containing an int and text which might be null +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32, Option)>() { + let (int_value, str_or_null): (i32, Option) = row?; + } +} +``` + +### Parsing row as a custom struct +It is possible to receive row as a struct with fields matching the columns.\ +The struct must: +* have the same number of fields as the number of queried columns +* have field types matching the columns being received +* derive `FromRow` + +Field names don't need to match column names. +```rust +use scylla::IntoTypedRows; +use scylla::macros::FromRow; +use scylla::frame::response::cql_to_rust::FromRow; + +#[derive(FromRow)] +struct MyRow { + age: i32, + name: Option +} + +// Parse row as two columns containing an int and text which might be null +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::() { + let my_row: MyRow = row?; + } +} +``` + +### Other data types +For parsing other data types see [Data Types](../data-types/data-types.md) \ No newline at end of file diff --git a/v0.12.0/_sources/queries/schema-agreement.md.txt b/v0.12.0/_sources/queries/schema-agreement.md.txt new file mode 100644 index 0000000000..a7163af7dd --- /dev/null +++ b/v0.12.0/_sources/queries/schema-agreement.md.txt @@ -0,0 +1,53 @@ +# Schema agreement + +Sometimes after performing queries some nodes have not been updated, so we need a mechanism that checks if every node have agreed on schema version. + +### Automated awaiting schema agreement + +The driver automatically awaits schema agreement after a schema-altering query is executed. +Waiting for schema agreement more than necessary is never a bug, but might slow down applications which do a lot of schema changes (e.g. a migration). +For instance, in case where somebody wishes to create a keyspace and then a lot of tables in it, it makes sense only to wait after creating a keyspace +and after creating all the tables rather than after every query. Therefore, the said behaviour can be disabled: + +```rust +let session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .auto_await_schema_agreement(false) + .build() + .await?; +``` + +### Manually awaiting schema agreement + +`Session::await_schema_agreement` returns a `Future` that can be `await`ed as long as schema is not in an agreement. +However, it won't wait forever; `SessionConfig` defines a timeout that limits the time of waiting. If the timeout elapses, +the return value is `Err(QueryError::RequestTimeout)`, otherwise it is `Ok(schema_version)`. + +```rust +session.await_schema_agreement().await?; +``` + +### Interval of checking for schema agreement + +If the schema is not agreed upon, the driver sleeps for a duration before checking it again. The default value is 200 milliseconds, +but it can be changed with `SessionBuilder::schema_agreement_interval`. + +```rust +SessionBuilder::new() + .known_node("127.0.0.1:9042") + .schema_agreement_interval(Duration::from_secs(1)) + .build() + .await?; +``` + +### Checking if schema is in agreement now + +If you want to check if schema is in agreement now, without retrying after failure, you can use `Session::check_schema_agreement` function. + +```rust +if session.check_schema_agreement().await?.is_some() { + println!("SCHEMA AGREED"); +} else { + println!("SCHEMA IS NOT IN AGREEMENT"); +} +``` diff --git a/v0.12.0/_sources/queries/simple.md.txt b/v0.12.0/_sources/queries/simple.md.txt new file mode 100644 index 0000000000..e908cbada4 --- /dev/null +++ b/v0.12.0/_sources/queries/simple.md.txt @@ -0,0 +1,84 @@ +# Simple query + +Simple query takes query text and values and simply executes them on a `Session`: +```rust +// Insert a value into the table +let to_insert: i32 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; +``` + +> ***Warning***\ +> Don't use simple query to receive large amounts of data.\ +> By default the query is unpaged and might cause heavy load on the cluster.\ +> In such cases set a page size and use [paged query](paged.md) instead.\ +> +> When page size is set, `query` will return only the first page of results. + +> ***Warning***\ +> If the values are not empty, driver first needs to send a `PREPARE` request +> in order to fetch information required to serialize values. This will affect +> performance because 2 round trips will be required instead of 1. + +### First argument - the query +As the first argument `Session::query` takes anything implementing `Into`.\ +You can create a query manually to set custom options. For example to change query consistency: +```rust +use scylla::query::Query; +use scylla::statement::Consistency; + +// Create a Query manually to change the Consistency to ONE +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_consistency(Consistency::One); + +// Insert a value into the table +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` +See [Query API documentation](https://docs.rs/scylla/latest/scylla/statement/query/struct.Query.html) for more options + +### Second argument - the values +Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.\ +Each `?` in query text will be filled with the matching value. + +The easiest way is to pass values using a tuple: +```rust +// Sending an integer and a string using a tuple +session + .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, 'text2')", (2_i32, "Some text")) + .await?; +``` +Here the first `?` will be filled with `2` and the second with `"Some text"`. +> **Never** pass values by adding strings, this could lead to [SQL Injection](https://en.wikipedia.org/wiki/SQL_injection) + +See [Query values](values.md) for more information about sending values in queries + +### Query result +`Session::query` returns `QueryResult` with rows represented as `Option>`.\ +Each row can be parsed as a tuple of rust types using `into_typed`: +```rust +use scylla::IntoTypedRows; + +// Query rows from the table and print them +if let Some(rows) = session.query("SELECT a FROM ks.tab", &[]).await?.rows { + // Parse each row as a tuple containing single i32 + for row in rows.into_typed::<(i32,)>() { + let read_row: (i32,) = row?; + println!("Read a value from row: {}", read_row.0); + } +} +``` +> In cases where page size is set, simple query returns only a single page of results.\ +> To receive all pages use a [paged query](paged.md) instead.\ + +See [Query result](result.md) for more information about handling query results + +### Performance +Simple queries should not be used in places where performance matters.\ +If performance matters use a [Prepared query](prepared.md) instead. + +With simple query the database has to parse query text each time it's executed, which worsens performance.\ + +Additionally token and shard aware load balancing does not work with simple queries. They are sent to random nodes. diff --git a/v0.12.0/_sources/queries/timeouts.md.txt b/v0.12.0/_sources/queries/timeouts.md.txt new file mode 100644 index 0000000000..16e4af1ca3 --- /dev/null +++ b/v0.12.0/_sources/queries/timeouts.md.txt @@ -0,0 +1,53 @@ +# Query timeouts + +Query execution time can be limited by setting a request timeout. If a query does not complete +in the given time, then `QueryError::RequestTimeout` is returned by the driver immediately, +so that application logic can continue operating, but the query may still be in progress on the server. + +As a side note, if one wishes custom server-side timeouts (i.e. actual interruption of query processing), +one can use a[`USING TIMEOUT ` directive supported in ScyllaDB](https://github.com/scylladb/scylladb/blob/master/docs/cql/cql-extensions.md#using-timeout) +(but not in Cassandra). + +Timeout can be set globally (per session) or locally (for given statement). +The default per-session timeout is currently 30s. +It is possible to turn off timeouts completely by providing `None` as timeout when building `Session`. +However, setting per-statement timeout to `None` results in falling back to per-session timeout. + +```rust +use scylla::{Session, SessionBuilder, query::Query}; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + +let no_timeout_profile_handle = ExecutionProfile::builder() + .request_timeout(None) // no timeout + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node(uri) + .default_execution_profile_handle(no_timeout_profile_handle) // no per-session timeout + .build() + .await?; + +// This query, having no timeout, could block indefinitely if a queried node hangs. +session + .query("TRUNCATE keyspace.table", ()) + .await?; + +let three_sec_timeout_profile_handle = ExecutionProfile::builder() + .request_timeout(Some(Duration::from_secs(3))) // no timeout + .build() + .into_handle(); + +// The below query will last for no more than 3 seconds, yielding a RequestTimeout error +// if no response arrives until then. +let mut query: Query = "TRUNCATE keyspace.table".into(); +query.set_execution_profile_handle(Some(three_sec_timeout_profile_handle)); +session + .query(query, ()) + .await?; + +``` diff --git a/v0.12.0/_sources/queries/usekeyspace.md.txt b/v0.12.0/_sources/queries/usekeyspace.md.txt new file mode 100644 index 0000000000..7b9afabeb6 --- /dev/null +++ b/v0.12.0/_sources/queries/usekeyspace.md.txt @@ -0,0 +1,77 @@ +# USE keyspace + +Using a keyspace allows to omit keyspace name in queries. + +For example in `cqlsh` one could write: +```sql +cqlsh> SELECT * FROM my_keyspace.table; + + a | b | +-------+-------+ + 12345 | 54321 | + +(1 rows) +cqlsh> USE my_keyspace; +cqlsh:my_keyspace> SELECT * FROM table; + + a | b | +-------+-------+ + 12345 | 54321 | + +(1 rows) + +``` +Tables from other keyspaces can still easily be accessed by using their keyspace names. +```sql +cqlsh:my_keyspace> SELECT * FROM other_keyspace.other_table; +``` + +In the driver this can be achieved using `Session::use_keyspace`: +```rust +session + .query("INSERT INTO my_keyspace.tab (a) VALUES ('test1')", &[]) + .await?; + +session.use_keyspace("my_keyspace", false).await?; + +// Now we can omit keyspace name in the query +session + .query("INSERT INTO tab (a) VALUES ('test2')", &[]) + .await?; +``` + +The first argument is the keyspace name.\ +The second argument states whether this name is case sensitive. + +It is also possible to send raw use keyspace query using `Session::query` instead of `Session::use_keyspace` such as: +```rust +session.query("USE my_keyspace", &[]).await?; +``` +This method has a slightly worse latency than `Session::use_keyspace` - there are two roundtrips needed instead of one. +Therefore, `Session::use_keyspace` is the preferred method for setting keyspaces. + +### Multiple use queries at once +Don't run multiple `use_keyspace` queries at once. +This could end up with half of connections using one keyspace and the other half using the other. + +### Case sensitivity + +In CQL a keyspace name can be case insensitive (without `"`) or case sensitive (with `"`).\ +If the second argument to `use_keyspace` is set to `true` this keyspace name will be wrapped in `"`.\ +It is best to avoid the problem altogether and just not create two keyspaces with the same name but different cases. + +Let's see what happens when there are two keyspaces with the same name but different cases: `my_keyspace` and `MY_KEYSPACE`: + +```rust +// lowercase name without case sensitivity will use my_keyspace +session.use_keyspace("my_keyspace", false).await?; + +// lowercase name with case sensitivity will use my_keyspace +session.use_keyspace("my_keyspace", true).await?; + +// uppercase name without case sensitivity will use my_keyspace +session.use_keyspace("MY_KEYSPACE", false).await?; + +// uppercase name with case sensitivity will use MY_KEYSPACE +session.use_keyspace("MY_KEYSPACE", true).await?; +``` diff --git a/v0.12.0/_sources/queries/values.md.txt b/v0.12.0/_sources/queries/values.md.txt new file mode 100644 index 0000000000..caddca4036 --- /dev/null +++ b/v0.12.0/_sources/queries/values.md.txt @@ -0,0 +1,125 @@ +# Query values +Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.\ +Each `?` in query text will be filled with the matching value. + +> **Never** pass values by adding strings, this could lead to [SQL Injection](https://en.wikipedia.org/wiki/SQL_injection) + +Each list of values to send in a query must implement the trait `SerializeRow`.\ +By default this can be a slice `&[]`, a tuple `()` (max 16 elements) of values to send, +or a custom struct which derives from `SerializeRow`. + +A few examples: +```rust +// Empty slice means that there are no values to send +session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?; + +// Empty tuple/unit also means that there are no values to send +session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?; + +// Sending three integers using a slice: +session + .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref()) + .await?; + +// Sending an integer and a string using a tuple +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text")) + .await?; + +// Sending an integer and a string using a named struct. +// Names of fields must match names of columns in request, +// but having them in the same order is not required. +// If the fields are in the same order, you can use attribute: +// `#[scylla(flavor = "enforce_order")]` +// in order to skip sorting the fields and just check if they +// are in the same order. See documentation of this macro +// for more information. +#[derive(SerializeRow)] +struct IntString { + a: i32, + b: String, +} + +let int_string = IntString { + a: 42_i32, + b: "hello".to_owned(), +}; + +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string) + .await?; + +// You can use named bind markers in query if you want +// your names in struct to be different than column names. +#[derive(SerializeRow)] +struct IntStringCustom { + first_value: i32, + second_value: String, +} + +let int_string_custom = IntStringCustom { + first_value: 42_i32, + second_value: "hello".to_owned(), +}; + +session + .query("INSERT INTO ks.tab (a, b) VALUES(:first_value, :second_value)", int_string_custom) + .await?; + +// Sending a single value as a tuple requires a trailing coma (Rust syntax): +session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?; + +// Each value can also be sent using a reference: +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text")) + .await?; + +// A map of named values can also be provided: +let mut vals: HashMap<&str, CqlValue> = HashMap::new(); +vals.insert("avalue", CqlValue::Text("hello".to_string())); +vals.insert("bvalue", CqlValue::Int(17)); +session + .query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals) + .await?; + +``` + +### `NULL` values +Null values can be sent using `Option<>` - sending a `None` will make the value `NULL`: +```rust +let null_i32: Option = None; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,)) + .await?; +``` + +### `Unset` values +When performing an insert with values which might be `NULL`, it's better to use `Unset`.\ +Database treats inserting `NULL` as a delete operation and will generate a tombstone. +Using `Unset` results in better performance: + +```rust +use scylla::frame::value::{MaybeUnset, Unset}; + +// Inserting a null results in suboptimal performance +let null_i32: Option = None; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,)) + .await?; + +// Using MaybeUnset enum is better +let unset_i32: MaybeUnset = MaybeUnset::Unset; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,)) + .await?; + +// If we are sure that a value should be unset we can simply use Unset +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,)) + .await?; +``` +See the [issue](https://issues.apache.org/jira/browse/CASSANDRA-7304) for more information about `Unset` + +### Other data types +See [Data Types](../data-types/data-types.md) for instructions on sending other data types diff --git a/v0.12.0/_sources/quickstart/create-project.md.txt b/v0.12.0/_sources/quickstart/create-project.md.txt new file mode 100644 index 0000000000..94ad1982b9 --- /dev/null +++ b/v0.12.0/_sources/quickstart/create-project.md.txt @@ -0,0 +1,34 @@ +# Creating a project + +To create a new project run: +```shell +cargo new myproject +``` + +In `Cargo.toml` add useful dependencies: +```toml +[dependencies] +scylla = "0.12" +tokio = { version = "1.12", features = ["full"] } +futures = "0.3.6" +uuid = "1.0" +bigdecimal = "0.4" +num-bigint = "0.3" +tracing = "0.1.36" +tracing-subscriber = { version = "0.3.14", features = ["env-filter"] } +``` + +In `main.rs` put: +```rust +use scylla::Session; + +#[tokio::main] +async fn main() { + println!("Hello scylla!"); +} +``` + +Now running `cargo run` should print: +```shell +Hello scylla! +``` diff --git a/v0.12.0/_sources/quickstart/example.md.txt b/v0.12.0/_sources/quickstart/example.md.txt new file mode 100644 index 0000000000..18a08a8300 --- /dev/null +++ b/v0.12.0/_sources/quickstart/example.md.txt @@ -0,0 +1,54 @@ +# Connecting and running a simple query + +Now everything is ready to use the driver. +Here is a small example: +```rust +use scylla::{IntoTypedRows, Session, SessionBuilder}; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new Session which connects to node at 127.0.0.1:9042 + // (or SCYLLA_URI if specified) + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .build() + .await?; + + // Create an example keyspace and table + session + .query( + "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \ + {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}", + &[], + ) + .await?; + + session + .query( + "CREATE TABLE IF NOT EXISTS ks.extab (a int primary key)", + &[], + ) + .await?; + + // Insert a value into the table + let to_insert: i32 = 12345; + session + .query("INSERT INTO ks.extab (a) VALUES(?)", (to_insert,)) + .await?; + + // Query rows from the table and print them + if let Some(rows) = session.query("SELECT a FROM ks.extab", &[]).await?.rows { + // Parse each row as a tuple containing single i32 + for row in rows.into_typed::<(i32,)>() { + let read_row: (i32,) = row?; + println!("Read a value from row: {}", read_row.0); + } + } + + Ok(()) +} +``` diff --git a/v0.12.0/_sources/quickstart/quickstart.md.txt b/v0.12.0/_sources/quickstart/quickstart.md.txt new file mode 100644 index 0000000000..b544aef743 --- /dev/null +++ b/v0.12.0/_sources/quickstart/quickstart.md.txt @@ -0,0 +1,23 @@ + +# Quick Start + + +In this chapter we will set up a Rust project and run a few simple queries. + +Topics Include: + +* [Create a Rust Project](create-project.md) +* [Example](example.md) +* [Install Scylla with Docker](scylla-docker.md) + + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + create-project + example + scylla* + +``` \ No newline at end of file diff --git a/v0.12.0/_sources/quickstart/scylla-docker.md.txt b/v0.12.0/_sources/quickstart/scylla-docker.md.txt new file mode 100644 index 0000000000..849bcbc10e --- /dev/null +++ b/v0.12.0/_sources/quickstart/scylla-docker.md.txt @@ -0,0 +1,23 @@ +# Running Scylla using Docker + +To make queries we will need a running Scylla instance. The easiest way is to use a [Docker](https://www.docker.com/) image.\ +Please [install Docker](https://docs.docker.com/engine/install) if it's not installed. + +### Running scylla +To start Scylla run: +```bash +# on Linux sudo might be required +docker run --rm -it -p 9042:9042 scylladb/scylla --smp 2 +``` + +Docker will download the image, then after minute or two there should be a message like: +```shell +Starting listening for CQL clients on 172.17.0.2:9042 +``` +This means that Scylla is ready to receive queries + +To stop this instance press `Ctrl + C` + +### More information +More information about this image can be found on [dockerhub](https://hub.docker.com/r/scylladb/scylla) + diff --git a/v0.12.0/_sources/retry-policy/default.md.txt b/v0.12.0/_sources/retry-policy/default.md.txt new file mode 100644 index 0000000000..590b503730 --- /dev/null +++ b/v0.12.0/_sources/retry-policy/default.md.txt @@ -0,0 +1,69 @@ +# Default retry policy +This is the retry policy used by default. It retries when there is a high chance that it might help.\ +This policy is based on the one in [DataStax Java Driver](https://docs.datastax.com/en/developer/java-driver/4.11/manual/core/retries/). +The behaviour is the same. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new()))); + +// You can also set retry policy in an execution profile +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; +prepared.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new()))); + +// You can also set retry policy in an execution profile +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); +prepared.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/v0.12.0/_sources/retry-policy/downgrading-consistency.md.txt b/v0.12.0/_sources/retry-policy/downgrading-consistency.md.txt new file mode 100644 index 0000000000..a13aea35f0 --- /dev/null +++ b/v0.12.0/_sources/retry-policy/downgrading-consistency.md.txt @@ -0,0 +1,108 @@ +# Downgrading consistency retry policy + +A retry policy that sometimes retries with a lower consistency level than the one initially +requested. +**BEWARE**: this policy may retry queries using a lower consistency level than the one +initially requested. By doing so, it may break consistency guarantees. In other words, if you use +this retry policy, there are cases (documented below) where a read at `Consistency::Quorum` **may +not** see a preceding write at `Consistency::Quorum`. Do not use this policy unless you have +understood the cases where this can happen and are ok with that. It is also highly recommended to +always log the occurrences of such consistency breaks. +This policy implements the same retries than the [DefaultRetryPolicy](default.md) policy. But on top +of that, it also retries in the following cases: + - On a read timeout: if the number of replicas that responded is greater than one, but lower + than is required by the requested consistency level, the operation is retried at a lower + consistency level. + - On a write timeout: if the operation is a `WriteType::UnloggedBatch` and at least one + replica acknowledged the write, the operation is retried at a lower consistency level. + Furthermore, for other operations, if at least one replica acknowledged the write, the + timeout is ignored. + - On an unavailable exception: if at least one replica is alive, the operation is retried at + a lower consistency level. + +The lower consistency level to use for retries is determined by the following rules: + - if more than 3 replicas responded, use `Consistency::Three`. + - if 1, 2 or 3 replicas responded, use the corresponding level `Consistency::One`, `Consistency::Two` or + `Consistency::Three`. + +Note that if the initial consistency level was `Consistency::EachQuorum`, Scylla returns the number +of live replicas _in the datacenter that failed to reach consistency_, not the overall +number in the cluster. Therefore if this number is 0, we still retry at `Consistency::One`, on the +assumption that a host may still be up in another datacenter. +The reasoning being this retry policy is the following one. If, based on the information the +Scylla coordinator node returns, retrying the operation with the initially requested +consistency has a chance to succeed, do it. Otherwise, if based on this information we know +**the initially requested consistency level cannot be achieved currently**, then: + - For writes, ignore the exception (thus silently failing the consistency requirement) if we + know the write has been persisted on at least one replica. + - For reads, try reading at a lower consistency level (thus silently failing the consistency + requirement). +In other words, this policy implements the idea that if the requested consistency level cannot be +achieved, the next best thing for writes is to make sure the data is persisted, and that reading +something is better than reading nothing, even if there is a risk of reading stale data. + +This policy is based on the one in [DataStax Java Driver](https://docs.datastax.com/en/drivers/java/3.11/com/datastax/driver/core/policies/DowngradingConsistencyRetryPolicy.html). +The behaviour is the same. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +prepared.set_execution_profile_handle(Some(handle)); + + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/v0.12.0/_sources/retry-policy/fallthrough.md.txt b/v0.12.0/_sources/retry-policy/fallthrough.md.txt new file mode 100644 index 0000000000..ca4cd44947 --- /dev/null +++ b/v0.12.0/_sources/retry-policy/fallthrough.md.txt @@ -0,0 +1,65 @@ +# Fallthrough retry policy + +The `FalthroughRetryPolicy` never retries, returns errors straight to the user. Useful for debugging. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +prepared.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/v0.12.0/_sources/retry-policy/retry-policy.md.txt b/v0.12.0/_sources/retry-policy/retry-policy.md.txt new file mode 100644 index 0000000000..68c4726dc0 --- /dev/null +++ b/v0.12.0/_sources/retry-policy/retry-policy.md.txt @@ -0,0 +1,48 @@ +# Retry policy configuration + +After a query fails the driver might decide to retry it based on its `Retry Policy` and the query itself. +Retry policy can be configured for `Session` or just for a single query. + +### Retry policies +By default there are three retry policies: +* [Fallthrough Retry Policy](fallthrough.md) - never retries, returns all errors straight to the user +* [Default Retry Policy](default.md) - used by default, might retry if there is a high chance of success +* [Downgrading Consistency Retry Policy](downgrading-consistency.md) - behaves as [Default Retry Policy](default.md), but also, + in some more cases, it retries **with lower `Consistency`**. + +It's possible to implement a custom `Retry Policy` by implementing the traits `RetryPolicy` and `RetrySession`. + +### Query idempotence +A query is idempotent if it can be applied multiple times without changing the result of the initial application + +Specifying that a query is idempotent increases the chances that it will be retried in case of failure. +Idempotent queries can be retried in situations where retrying non idempotent queries would be dangerous. + +Idempotence has to be specified manually, the driver is not able to figure it out by itself. +```rust +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; + +// Specify that a Query is idempotent +let mut my_query: Query = Query::new("SELECT a FROM ks.tab"); +my_query.set_is_idempotent(true); + + +// Specify that a PreparedStatement is idempotent +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +prepared.set_is_idempotent(true); +``` + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + fallthrough + default + downgrading-consistency + +``` diff --git a/v0.12.0/_sources/schema/schema.md.txt b/v0.12.0/_sources/schema/schema.md.txt new file mode 100644 index 0000000000..19a5bc9751 --- /dev/null +++ b/v0.12.0/_sources/schema/schema.md.txt @@ -0,0 +1,60 @@ +# Schema + +The driver is capable of fetching database schema and presenting it to its users. + +## Fetching schema + +Fetching database schema occurs periodically, but it can also be done on-demand. In order to fetch the newest database schema, one can call `refresh_metadata()` on a Session instance: +```rust + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + // Schema metadata will be fetched below + session.refresh_metadata().await?; + Ok(()) +} +``` + +## Inspecting schema + +Once fetched, a snapshot of cluster's schema can be examined. The following information can be obtained: + - keyspace + - tables belonging to the keyspace + - materialized views belonging to the keyspace + - replication strategy + - user-defined types + - table/view + - primary key definition + - columns + - partitioner type + +Example showing how to print obtained schema information: + +```rust + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + // Schema metadata will be fetched below + session.refresh_metadata().await?; + + let cluster_data = &session.get_cluster_data(); + let keyspaces = &cluster_data.get_keyspace_info(); + + for (keyspace_name, keyspace_info) in keyspaces.iter() { + println!("Keyspace {}:", keyspace_name); + println!("\tTables: {:#?}", keyspace_info.tables); + println!("\tViews: {:#?}", keyspace_info.views); + println!("\tUDTs: {:#?}", keyspace_info.user_defined_types); + } + + Ok(()) +} +``` diff --git a/v0.12.0/_sources/speculative-execution/percentile.md.txt b/v0.12.0/_sources/speculative-execution/percentile.md.txt new file mode 100644 index 0000000000..c82c24a925 --- /dev/null +++ b/v0.12.0/_sources/speculative-execution/percentile.md.txt @@ -0,0 +1,34 @@ +# Percentile speculative execution + +This policy has access to `Metrics` shared with session, and triggers +speculative execution when the request to the current host is above a +given percentile. + + +### Example +To use this policy in `Session`: +```rust +use std::{sync::Arc, time::Duration}; +use scylla::{ + Session, + SessionBuilder, + speculative_execution::PercentileSpeculativeExecutionPolicy, + transport::execution_profile::ExecutionProfile, +}; + +let policy = PercentileSpeculativeExecutionPolicy { + max_retry_count: 3, + percentile: 99.0, +}; + +let handle = ExecutionProfile::builder() + .speculative_execution_policy(Some(Arc::new(policy))) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` diff --git a/v0.12.0/_sources/speculative-execution/simple.md.txt b/v0.12.0/_sources/speculative-execution/simple.md.txt new file mode 100644 index 0000000000..dd17db55d6 --- /dev/null +++ b/v0.12.0/_sources/speculative-execution/simple.md.txt @@ -0,0 +1,34 @@ +# Simple speculative execution + +The easiest speculative execution policy available. It starts another +execution of a query after constant delay of `retry_interval` and does at most +`max_retry_count` speculative query executions (not counting the first, +non-speculative one). + +### Example +To use this policy in `Session`: +```rust +use std::{sync::Arc, time::Duration}; +use scylla::{ + Session, + SessionBuilder, + speculative_execution::SimpleSpeculativeExecutionPolicy, + transport::execution_profile::ExecutionProfile, +}; + +let policy = SimpleSpeculativeExecutionPolicy { + max_retry_count: 3, + retry_interval: Duration::from_millis(100), +}; + +let handle = ExecutionProfile::builder() + .speculative_execution_policy(Some(Arc::new(policy))) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` diff --git a/v0.12.0/_sources/speculative-execution/speculative.md.txt b/v0.12.0/_sources/speculative-execution/speculative.md.txt new file mode 100644 index 0000000000..d6e2ae0422 --- /dev/null +++ b/v0.12.0/_sources/speculative-execution/speculative.md.txt @@ -0,0 +1,26 @@ +# Speculative execution + +Speculative query execution is an optimization technique where a driver +pre-emptively starts a second execution of a query against another node, +before the first node has replied. + +There are multiple speculative execution strategies that the driver can use. +Speculative execution can be configured for the whole whole `Session` during +its creation. + +Available speculative execution strategies: +* [Simple](simple.md) +* [Latency Percentile](percentile.md) + +Speculative execution is not enabled by default, and currently only +non-iter session methods use it. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + simple + percentile + +``` \ No newline at end of file diff --git a/v0.12.0/_sources/tracing/basic.md.txt b/v0.12.0/_sources/tracing/basic.md.txt new file mode 100644 index 0000000000..73a6cb227c --- /dev/null +++ b/v0.12.0/_sources/tracing/basic.md.txt @@ -0,0 +1,74 @@ +# Tracing a simple/prepared/batch query + +[Simple query](../queries/simple.md), [prepared query](../queries/prepared.md) and [batch query](../queries/batch.md) +return a `QueryResult` which contains a `tracing_id` if tracing was enabled. + +### Tracing a simple query +```rust +use scylla::query::Query; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Create a Query manually and enable tracing +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)"); +query.set_tracing(true); + +let res: QueryResult = session.query(query, &[]).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing a prepared query +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Prepare the query +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +// Enable tracing for the prepared query +prepared.set_tracing(true); + +let res: QueryResult = session.execute(&prepared, &[]).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing a batch query +```rust +use scylla::batch::Batch; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Create a batch statement +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.tab (a) VALUES(4)"); + +// Enable tracing +batch.set_tracing(true); + +let res: QueryResult = session.batch(&batch, ((),)).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/v0.12.0/_sources/tracing/paged.md.txt b/v0.12.0/_sources/tracing/paged.md.txt new file mode 100644 index 0000000000..e7424e6ddd --- /dev/null +++ b/v0.12.0/_sources/tracing/paged.md.txt @@ -0,0 +1,65 @@ +# Tracing a paged query + +A paged query performs multiple simple/prepared queries to query subsequent pages.\ +If tracing is enabled the row iterator will contain a list of tracing ids for all performed queries. + + +### Tracing `Session::query_iter` +```rust +use scylla::query::Query; +use scylla::transport::iterator::RowIterator; +use scylla::tracing::TracingInfo; +use futures::StreamExt; +use uuid::Uuid; + +// Create a Query manually and enable tracing +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)"); +query.set_tracing(true); + +// Create a paged query iterator and fetch pages +let mut row_iterator: RowIterator = session.query_iter(query, &[]).await?; +while let Some(_row) = row_iterator.next().await { + // Receive rows +} + +// Now there are tracing ids for each performed query +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids(); + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing `Session::execute_iter` +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::iterator::RowIterator; +use scylla::tracing::TracingInfo; +use futures::StreamExt; +use uuid::Uuid; + +// Prepare the query +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +// Enable tracing for the prepared query +prepared.set_tracing(true); + +// Create a paged query iterator and fetch pages +let mut row_iterator: RowIterator = session.execute_iter(prepared, &[]).await?; +while let Some(_row) = row_iterator.next().await { + // Receive rows +} + +// Now there are tracing ids for each performed query +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids(); + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/v0.12.0/_sources/tracing/prepare.md.txt b/v0.12.0/_sources/tracing/prepare.md.txt new file mode 100644 index 0000000000..98ceafe5d3 --- /dev/null +++ b/v0.12.0/_sources/tracing/prepare.md.txt @@ -0,0 +1,27 @@ +# Tracing `Session::prepare` + +`Session::prepare` prepares a query on all connections. If tracing is enabled for the `Query` to prepare, the resulting `PreparedStatement` will contain `prepare_tracing_ids`. `prepare_tracing_ids` is a list of tracing ids of prepare requests on all connections. + +```rust +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Prepare the query with tracing enabled +let mut to_prepare: Query = Query::new("SELECT a FROM ks.tab"); +to_prepare.set_tracing(true); + +let mut prepared: PreparedStatement = session + .prepare(to_prepare) + .await?; + +// Now there are tracing ids for each prepare request +let tracing_ids: &[Uuid] = &prepared.prepare_tracing_ids; + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/v0.12.0/_sources/tracing/query-history.md.txt b/v0.12.0/_sources/tracing/query-history.md.txt new file mode 100644 index 0000000000..feb7c86be2 --- /dev/null +++ b/v0.12.0/_sources/tracing/query-history.md.txt @@ -0,0 +1,106 @@ +# Query Execution History + +The driver allows to collect history of query execution.\ +This history includes all requests sent, decisions to retry and speculative execution fibers started. + +## Example code + +```rust +use scylla::query::Query; +use scylla::history::{HistoryCollector, StructuredHistory}; +use std::sync::Arc; + +// Create a query for which we would like to trace the history of its execution +let mut query: Query = Query::new("SELECT * FROM ks.t"); + +// Create a history collector and pass it to the query +let history_listener = Arc::new(HistoryCollector::new()); +query.set_history_listener(history_listener.clone()); + +// Run the query, doesn't matter if it failed, the history will still be saved +let _ignore_error = session.query(query.clone(), ()).await; + +// Access the collected history and print it +let structured_history: StructuredHistory = history_listener.clone_structured_history(); +println!("Query history: {}", structured_history); +``` +To see more check out the [example code](https://github.com/scylladb/scylla-rust-driver/blob/main/examples/query_history.rs) + +## Output + +Sample output for a query that didn't encounter any difficulties: +```none +=== Query #0 === +| start_time: 2022-08-25 11:21:50.445075147 UTC +| Non-speculative attempts: +| - Attempt #0 sent to 127.0.0.1:9042 +| request send time: 2022-08-25 11:21:50.445151628 UTC +| Success at 2022-08-25 11:21:50.447444362 UTC +| +| Query successful at 2022-08-25 11:21:50.447447970 UTC +================= +``` + +Here's output for a query that had some trouble - nodes didn't respond and speculative execution decided to query others in parallel. +Finally the third node provided a response. +```none +=== Query #0 === +| start_time: 2022-08-26 15:08:28.525367409 UTC +| Non-speculative attempts: +| - Attempt #0 sent to 127.0.0.219:9042 +| request send time: 2022-08-26 15:08:28.525409294 UTC +| No result yet +| +| +| > Speculative fiber #0 +| fiber start time: 2022-08-26 15:08:28.537074167 UTC +| - Attempt #0 sent to 127.0.0.217:9042 +| request send time: 2022-08-26 15:08:28.537126083 UTC +| No result yet +| +| +| > Speculative fiber #1 +| fiber start time: 2022-08-26 15:08:28.548050242 UTC +| - Attempt #0 sent to 127.0.0.218:9042 +| request send time: 2022-08-26 15:08:28.548089083 UTC +| Success at 2022-08-26 15:08:28.590052778 UTC +| +| Query successful at 2022-08-26 15:08:28.590078119 UTC +================= +``` + +## How the driver executes queries + +To read the output it's useful to understand more about how the driver executes queries. + +### No speculative execution +Without speculative execution the driver performs many attempts sequentially until one of them succeeds. +A single attempt consists of sending a request to some node and waiting for the answer. +In case of an error the driver consults the retry policy to decide what to do next. +The decision might be to fail the query, retry on the same node, another node, change query parameters, etc. +Once the decision is made either the query fails or another attempt is started. This continues until the query ends. + +### Speculative execution +When speculative execution is enabled at first the driver doesn't care about it - it does the attempts sequentially and tries to get an answer. +However once a specified amount of time has passed it will decide to try new attempts in parallel +hoping that another node will be able to answer quicker. +This is done by spawning a speculative fiber. Each spawned fiber performs sequential attempts just like in non-speculative execution. +Many fibers can be spawned if the answer wasn't acquired in time. + +### StructuredHistory +[`StructuredHistory`](https://docs.rs/scylla/latest/scylla/history/struct.StructuredHistory.html) +is a history representation that represents the history by listing attempts for each speculative fiber. + +## HistoryListener trait, custom history collecting + +History can be collected by any struct implementing the +[`HistoryListener`](https://docs.rs/scylla/latest/scylla/history/trait.HistoryListener.html) trait. + +The implementation of `HistoryListener` provided by this crate is the +[`HistoryCollector`](https://docs.rs/scylla/latest/scylla/history/struct.HistoryCollector.html). +`HistoryCollector` simply collects all events along with their timestamps. + +Information collected by `HistoryCollector` is just a stream of events, in order to analyze it it's possible +to convert it to a structured representation. +[`StructuredHistory`](https://docs.rs/scylla/latest/scylla/history/struct.StructuredHistory.html) +can be created by calling `HistoryCollector::clone_structured_history()`. diff --git a/v0.12.0/_sources/tracing/tracing.md.txt b/v0.12.0/_sources/tracing/tracing.md.txt new file mode 100644 index 0000000000..75ea2d5fee --- /dev/null +++ b/v0.12.0/_sources/tracing/tracing.md.txt @@ -0,0 +1,41 @@ +# Query tracing + +The driver has utilities for monitoring the execution of queries. +There are two separate ways to get information about what happened with a query: `Tracing` and `Query Execution History`. + +### Tracing + +Tracing is a feature provided by Scylla. When sending a query we can set a flag that signifies that we would like it to be traced. +After completing the query Scylla provides a `tracing_id` which can be used to fetch information about it - which nodes it was sent to, what operations were performed etc. + +Queries that support tracing: +* [`Session::query()`](basic.md) +* [`Session::query_iter()`](paged.md) +* [`Session::execute()`](basic.md) +* [`Session::execute_iter()`](paged.md) +* [`Session::batch()`](basic.md) +* [`Session::prepare()`](prepare.md) + +After obtaining the tracing id you can use `Session::get_tracing_info()` to query tracing information.\ +`TracingInfo` contains values that are the same in Scylla and Cassandra®, skipping any database-specific ones.\ +If `TracingInfo` does not contain some needed value it's possible to query it manually from the tables +`system_traces.sessions` and `system_traces.events` + +### Query Execution History + +Tracing provides information about how the query execution went on database nodes, but it doesn't say anything about what was going on inside the driver.\ +This is what query execution history was made for. + +It allows to follow what the driver was thinking - all query attempts, retry decisions, speculative executions. +More information is available in the [Query Execution History](query-history.md) chapter. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + basic + paged + prepare + query-history +``` \ No newline at end of file diff --git a/v0.12.0/_static/basic.css b/v0.12.0/_static/basic.css new file mode 100644 index 0000000000..30fee9d0f7 --- /dev/null +++ b/v0.12.0/_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/v0.12.0/_static/check-solid.svg b/v0.12.0/_static/check-solid.svg new file mode 100644 index 0000000000..92fad4b5c0 --- /dev/null +++ b/v0.12.0/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v0.12.0/_static/clipboard.min.js b/v0.12.0/_static/clipboard.min.js new file mode 100644 index 0000000000..54b3c46381 --- /dev/null +++ b/v0.12.0/_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/v0.12.0/_static/copybutton.css b/v0.12.0/_static/copybutton.css new file mode 100644 index 0000000000..f1916ec7d1 --- /dev/null +++ b/v0.12.0/_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/v0.12.0/_static/copybutton.js b/v0.12.0/_static/copybutton.js new file mode 100644 index 0000000000..2ea7ff3e21 --- /dev/null +++ b/v0.12.0/_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/v0.12.0/_static/copybutton_funcs.js b/v0.12.0/_static/copybutton_funcs.js new file mode 100644 index 0000000000..dbe1aaad79 --- /dev/null +++ b/v0.12.0/_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/v0.12.0/_static/css/main.css b/v0.12.0/_static/css/main.css new file mode 100644 index 0000000000..65eb0a5536 --- /dev/null +++ b/v0.12.0/_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/v0.12.0/_static/doctools.js b/v0.12.0/_static/doctools.js new file mode 100644 index 0000000000..d06a71d751 --- /dev/null +++ b/v0.12.0/_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/v0.12.0/_static/documentation_options.js b/v0.12.0/_static/documentation_options.js new file mode 100644 index 0000000000..7e4c114f21 --- /dev/null +++ b/v0.12.0/_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/v0.12.0/_static/file.png b/v0.12.0/_static/file.png new file mode 100644 index 0000000000..a858a410e4 Binary files /dev/null and b/v0.12.0/_static/file.png differ diff --git a/v0.12.0/_static/img/banner-background.svg b/v0.12.0/_static/img/banner-background.svg new file mode 100644 index 0000000000..f8520d5b3e --- /dev/null +++ b/v0.12.0/_static/img/banner-background.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v0.12.0/_static/img/favicon-228x228.png b/v0.12.0/_static/img/favicon-228x228.png new file mode 100644 index 0000000000..f30770c7ed Binary files /dev/null and b/v0.12.0/_static/img/favicon-228x228.png differ diff --git a/v0.12.0/_static/img/favicon-32x32.png b/v0.12.0/_static/img/favicon-32x32.png new file mode 100644 index 0000000000..aae1708f26 Binary files /dev/null and b/v0.12.0/_static/img/favicon-32x32.png differ diff --git a/v0.12.0/_static/img/favicon.ico b/v0.12.0/_static/img/favicon.ico new file mode 100644 index 0000000000..6c7484f082 Binary files /dev/null and b/v0.12.0/_static/img/favicon.ico differ diff --git a/v0.12.0/_static/img/icons/icon-about-team.svg b/v0.12.0/_static/img/icons/icon-about-team.svg new file mode 100644 index 0000000000..5448c7f007 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-about-team.svg @@ -0,0 +1 @@ +icon-about-team diff --git a/v0.12.0/_static/img/icons/icon-about-us-m.svg b/v0.12.0/_static/img/icons/icon-about-us-m.svg new file mode 100644 index 0000000000..09107d9520 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-about-us-m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.12.0/_static/img/icons/icon-about-us.svg b/v0.12.0/_static/img/icons/icon-about-us.svg new file mode 100644 index 0000000000..1b1fcc83e3 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-about-us.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.12.0/_static/img/icons/icon-alternator.svg b/v0.12.0/_static/img/icons/icon-alternator.svg new file mode 100644 index 0000000000..7c2b4ebae0 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-alternator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.12.0/_static/img/icons/icon-apps.svg b/v0.12.0/_static/img/icons/icon-apps.svg new file mode 100644 index 0000000000..7e93612026 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-apps.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-architecture.svg b/v0.12.0/_static/img/icons/icon-architecture.svg new file mode 100644 index 0000000000..67ebbc2f38 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-architecture.svg @@ -0,0 +1 @@ +icon-architecture diff --git a/v0.12.0/_static/img/icons/icon-benchmarks.svg b/v0.12.0/_static/img/icons/icon-benchmarks.svg new file mode 100644 index 0000000000..e1ce2c1d78 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-benchmarks.svg @@ -0,0 +1 @@ +icon-benchmarks diff --git a/v0.12.0/_static/img/icons/icon-blog.svg b/v0.12.0/_static/img/icons/icon-blog.svg new file mode 100644 index 0000000000..f4096cbf11 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-blog.svg @@ -0,0 +1 @@ +icon-blog2 diff --git a/v0.12.0/_static/img/icons/icon-careers.svg b/v0.12.0/_static/img/icons/icon-careers.svg new file mode 100644 index 0000000000..2a7c6ea0b7 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-careers.svg @@ -0,0 +1 @@ +icon-careers diff --git a/v0.12.0/_static/img/icons/icon-chevron-left.svg b/v0.12.0/_static/img/icons/icon-chevron-left.svg new file mode 100644 index 0000000000..3afa25c481 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/v0.12.0/_static/img/icons/icon-chevron-right.svg b/v0.12.0/_static/img/icons/icon-chevron-right.svg new file mode 100644 index 0000000000..44eb829cdc --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/v0.12.0/_static/img/icons/icon-circe.svg b/v0.12.0/_static/img/icons/icon-circe.svg new file mode 100644 index 0000000000..875e421670 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-circe.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-clock.svg b/v0.12.0/_static/img/icons/icon-clock.svg new file mode 100644 index 0000000000..8c92469808 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-clock.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-close.svg b/v0.12.0/_static/img/icons/icon-close.svg new file mode 100644 index 0000000000..d1162b73e7 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-close.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/v0.12.0/_static/img/icons/icon-cloud-docs.svg b/v0.12.0/_static/img/icons/icon-cloud-docs.svg new file mode 100644 index 0000000000..a9069bb6e5 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-cloud-docs.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-cloud.svg b/v0.12.0/_static/img/icons/icon-cloud.svg new file mode 100644 index 0000000000..cfb2318dae --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.12.0/_static/img/icons/icon-comparison.svg b/v0.12.0/_static/img/icons/icon-comparison.svg new file mode 100644 index 0000000000..49d809a5df --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-comparison.svg @@ -0,0 +1 @@ +icon-comparison diff --git a/v0.12.0/_static/img/icons/icon-contact-us.svg b/v0.12.0/_static/img/icons/icon-contact-us.svg new file mode 100644 index 0000000000..9df3145dd2 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-contact-us.svg @@ -0,0 +1 @@ +icon-contact-us diff --git a/v0.12.0/_static/img/icons/icon-developers-blog.svg b/v0.12.0/_static/img/icons/icon-developers-blog.svg new file mode 100644 index 0000000000..ee804197a0 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-developers-blog.svg @@ -0,0 +1 @@ +icon-developers-blog diff --git a/v0.12.0/_static/img/icons/icon-docs.svg b/v0.12.0/_static/img/icons/icon-docs.svg new file mode 100644 index 0000000000..5501492f3e --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-docs.svg @@ -0,0 +1 @@ +icon-docs diff --git a/v0.12.0/_static/img/icons/icon-enterprise-m.svg b/v0.12.0/_static/img/icons/icon-enterprise-m.svg new file mode 100644 index 0000000000..97be900b50 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-enterprise-m.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.12.0/_static/img/icons/icon-enterprise.svg b/v0.12.0/_static/img/icons/icon-enterprise.svg new file mode 100644 index 0000000000..ee1ac26283 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.12.0/_static/img/icons/icon-events.svg b/v0.12.0/_static/img/icons/icon-events.svg new file mode 100644 index 0000000000..ba5f211864 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-events.svg @@ -0,0 +1 @@ +icon-events diff --git a/v0.12.0/_static/img/icons/icon-exclamation.svg b/v0.12.0/_static/img/icons/icon-exclamation.svg new file mode 100644 index 0000000000..a7eb4b77a4 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-exclamation.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v0.12.0/_static/img/icons/icon-expand.svg b/v0.12.0/_static/img/icons/icon-expand.svg new file mode 100644 index 0000000000..3806565367 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-expand.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/v0.12.0/_static/img/icons/icon-forum.svg b/v0.12.0/_static/img/icons/icon-forum.svg new file mode 100644 index 0000000000..37a709f7a8 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-forum.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-getting-started.svg b/v0.12.0/_static/img/icons/icon-getting-started.svg new file mode 100644 index 0000000000..702500be40 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-getting-started.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-glossary.svg b/v0.12.0/_static/img/icons/icon-glossary.svg new file mode 100644 index 0000000000..e8329c2afe --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-glossary.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-home.svg b/v0.12.0/_static/img/icons/icon-home.svg new file mode 100644 index 0000000000..f0b9c25419 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-home.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-infoworld.svg b/v0.12.0/_static/img/icons/icon-infoworld.svg new file mode 100644 index 0000000000..906e87279c --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-infoworld.svg @@ -0,0 +1 @@ +icon-infoworld diff --git a/v0.12.0/_static/img/icons/icon-integrations.svg b/v0.12.0/_static/img/icons/icon-integrations.svg new file mode 100644 index 0000000000..1ef0920d49 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-integrations.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-knowledge-base.svg b/v0.12.0/_static/img/icons/icon-knowledge-base.svg new file mode 100644 index 0000000000..884451270d --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-knowledge-base.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-less.svg b/v0.12.0/_static/img/icons/icon-less.svg new file mode 100644 index 0000000000..3094127dec --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-less.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v0.12.0/_static/img/icons/icon-live-test.svg b/v0.12.0/_static/img/icons/icon-live-test.svg new file mode 100644 index 0000000000..dcb5916c26 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-live-test.svg @@ -0,0 +1 @@ +icon-live-test diff --git a/v0.12.0/_static/img/icons/icon-mail-list.svg b/v0.12.0/_static/img/icons/icon-mail-list.svg new file mode 100644 index 0000000000..0e6192a352 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-mail-list.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-manager.svg b/v0.12.0/_static/img/icons/icon-manager.svg new file mode 100644 index 0000000000..02b4e425be --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-manager.svg @@ -0,0 +1 @@ +icon-manager diff --git a/v0.12.0/_static/img/icons/icon-memory-management.svg b/v0.12.0/_static/img/icons/icon-memory-management.svg new file mode 100644 index 0000000000..e34eb4504f --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-memory-management.svg @@ -0,0 +1 @@ +icon-memory-management diff --git a/v0.12.0/_static/img/icons/icon-modeling.svg b/v0.12.0/_static/img/icons/icon-modeling.svg new file mode 100644 index 0000000000..97fa3a0e21 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-modeling.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-monitoring.svg b/v0.12.0/_static/img/icons/icon-monitoring.svg new file mode 100644 index 0000000000..80b3787f66 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-monitoring.svg @@ -0,0 +1 @@ +icon-monitoring diff --git a/v0.12.0/_static/img/icons/icon-networking.svg b/v0.12.0/_static/img/icons/icon-networking.svg new file mode 100644 index 0000000000..40a3fd5f6f --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-networking.svg @@ -0,0 +1 @@ +icon-networking diff --git a/v0.12.0/_static/img/icons/icon-news.svg b/v0.12.0/_static/img/icons/icon-news.svg new file mode 100644 index 0000000000..a952b59937 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-news.svg @@ -0,0 +1 @@ +icon-news diff --git a/v0.12.0/_static/img/icons/icon-newsletter.svg b/v0.12.0/_static/img/icons/icon-newsletter.svg new file mode 100644 index 0000000000..5b8d47eb15 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-newsletter.svg @@ -0,0 +1 @@ +icon-newsletter diff --git a/v0.12.0/_static/img/icons/icon-nsql-guides.svg b/v0.12.0/_static/img/icons/icon-nsql-guides.svg new file mode 100644 index 0000000000..60ebab3795 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-nsql-guides.svg @@ -0,0 +1 @@ +icon-nsql-guides diff --git a/v0.12.0/_static/img/icons/icon-open-source.svg b/v0.12.0/_static/img/icons/icon-open-source.svg new file mode 100644 index 0000000000..98c2ea7d5b --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-open-source.svg @@ -0,0 +1 @@ +icon-open-source diff --git a/v0.12.0/_static/img/icons/icon-operator.svg b/v0.12.0/_static/img/icons/icon-operator.svg new file mode 100644 index 0000000000..bb7d8d3ea8 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-operator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.12.0/_static/img/icons/icon-overview.svg b/v0.12.0/_static/img/icons/icon-overview.svg new file mode 100644 index 0000000000..515c1528a2 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-overview.svg @@ -0,0 +1 @@ +icon-overview diff --git a/v0.12.0/_static/img/icons/icon-partners.svg b/v0.12.0/_static/img/icons/icon-partners.svg new file mode 100644 index 0000000000..d0146fc497 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-partners.svg @@ -0,0 +1 @@ +icon-partners diff --git a/v0.12.0/_static/img/icons/icon-plus.svg b/v0.12.0/_static/img/icons/icon-plus.svg new file mode 100644 index 0000000000..5757435085 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-plus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v0.12.0/_static/img/icons/icon-pricing.svg b/v0.12.0/_static/img/icons/icon-pricing.svg new file mode 100644 index 0000000000..74b01db168 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-pricing.svg @@ -0,0 +1 @@ +icon-pricing$ diff --git a/v0.12.0/_static/img/icons/icon-release-notes.svg b/v0.12.0/_static/img/icons/icon-release-notes.svg new file mode 100644 index 0000000000..80c490c7b0 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-release-notes.svg @@ -0,0 +1 @@ +icon-release-notes diff --git a/v0.12.0/_static/img/icons/icon-resource-center.svg b/v0.12.0/_static/img/icons/icon-resource-center.svg new file mode 100644 index 0000000000..6e3ab08e79 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-resource-center.svg @@ -0,0 +1 @@ +icon-ressource-center diff --git a/v0.12.0/_static/img/icons/icon-roadmap.svg b/v0.12.0/_static/img/icons/icon-roadmap.svg new file mode 100644 index 0000000000..c8cbf67c8c --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-roadmap.svg @@ -0,0 +1 @@ +icon-roadmap-4 diff --git a/v0.12.0/_static/img/icons/icon-search.svg b/v0.12.0/_static/img/icons/icon-search.svg new file mode 100644 index 0000000000..81aae93eef --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v0.12.0/_static/img/icons/icon-slack.svg b/v0.12.0/_static/img/icons/icon-slack.svg new file mode 100644 index 0000000000..fc164ea1e7 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-slack.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-stack-overflow.svg b/v0.12.0/_static/img/icons/icon-stack-overflow.svg new file mode 100644 index 0000000000..bebe9b8274 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v0.12.0/_static/img/icons/icon-summit.svg b/v0.12.0/_static/img/icons/icon-summit.svg new file mode 100644 index 0000000000..4b900bd0c0 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-summit.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/icons/icon-support.svg b/v0.12.0/_static/img/icons/icon-support.svg new file mode 100644 index 0000000000..a4228b34e8 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-support.svg @@ -0,0 +1 @@ +icon-support diff --git a/v0.12.0/_static/img/icons/icon-tech-talks.svg b/v0.12.0/_static/img/icons/icon-tech-talks.svg new file mode 100644 index 0000000000..df42b5522b --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-tech-talks.svg @@ -0,0 +1 @@ +icon-tech-talks diff --git a/v0.12.0/_static/img/icons/icon-testing.svg b/v0.12.0/_static/img/icons/icon-testing.svg new file mode 100644 index 0000000000..2fe54efdbc --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-testing.svg @@ -0,0 +1 @@ +icon-testing diff --git a/v0.12.0/_static/img/icons/icon-thumbs-down.svg b/v0.12.0/_static/img/icons/icon-thumbs-down.svg new file mode 100644 index 0000000000..3e7bcd6d90 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.12.0/_static/img/icons/icon-thumbs-up.svg b/v0.12.0/_static/img/icons/icon-thumbs-up.svg new file mode 100644 index 0000000000..226c44d853 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.12.0/_static/img/icons/icon-tip.svg b/v0.12.0/_static/img/icons/icon-tip.svg new file mode 100644 index 0000000000..bf7aa6af84 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-tip.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/v0.12.0/_static/img/icons/icon-training.svg b/v0.12.0/_static/img/icons/icon-training.svg new file mode 100644 index 0000000000..08b95a88ed --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-training.svg @@ -0,0 +1 @@ +icon-training diff --git a/v0.12.0/_static/img/icons/icon-triangle-down.svg b/v0.12.0/_static/img/icons/icon-triangle-down.svg new file mode 100644 index 0000000000..e8ae088106 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-triangle-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/v0.12.0/_static/img/icons/icon-university.svg b/v0.12.0/_static/img/icons/icon-university.svg new file mode 100644 index 0000000000..f7547ab959 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-university.svg @@ -0,0 +1 @@ +icon-university diff --git a/v0.12.0/_static/img/icons/icon-users-blog.svg b/v0.12.0/_static/img/icons/icon-users-blog.svg new file mode 100644 index 0000000000..47e56cddcf --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-users-blog.svg @@ -0,0 +1 @@ +icon-users-blog diff --git a/v0.12.0/_static/img/icons/icon-warning.svg b/v0.12.0/_static/img/icons/icon-warning.svg new file mode 100644 index 0000000000..e4b1d40331 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-warning.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v0.12.0/_static/img/icons/icon-webinars.svg b/v0.12.0/_static/img/icons/icon-webinars.svg new file mode 100644 index 0000000000..5e9f5cd427 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-webinars.svg @@ -0,0 +1 @@ +icon-webinars diff --git a/v0.12.0/_static/img/icons/icon-whitepapers.svg b/v0.12.0/_static/img/icons/icon-whitepapers.svg new file mode 100644 index 0000000000..3351e51d23 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-whitepapers.svg @@ -0,0 +1 @@ +icon-whitepapers diff --git a/v0.12.0/_static/img/icons/icon-workshop.svg b/v0.12.0/_static/img/icons/icon-workshop.svg new file mode 100644 index 0000000000..5206e58e98 --- /dev/null +++ b/v0.12.0/_static/img/icons/icon-workshop.svg @@ -0,0 +1 @@ + diff --git a/v0.12.0/_static/img/logo-docs.svg b/v0.12.0/_static/img/logo-docs.svg new file mode 100644 index 0000000000..4fff669cb6 --- /dev/null +++ b/v0.12.0/_static/img/logo-docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.12.0/_static/img/logo-scylla-horizontal-RGB.svg b/v0.12.0/_static/img/logo-scylla-horizontal-RGB.svg new file mode 100644 index 0000000000..b5022d7c4d --- /dev/null +++ b/v0.12.0/_static/img/logo-scylla-horizontal-RGB.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.12.0/_static/img/mascots/404.jpg b/v0.12.0/_static/img/mascots/404.jpg new file mode 100644 index 0000000000..769fa0889f Binary files /dev/null and b/v0.12.0/_static/img/mascots/404.jpg differ diff --git a/v0.12.0/_static/img/mascots/scylla-3monsters.png b/v0.12.0/_static/img/mascots/scylla-3monsters.png new file mode 100644 index 0000000000..7c06d01674 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-3monsters.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-advisor-crystal.png b/v0.12.0/_static/img/mascots/scylla-advisor-crystal.png new file mode 100644 index 0000000000..d33fddd62f Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-advisor-crystal.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-alternator.svg b/v0.12.0/_static/img/mascots/scylla-alternator.svg new file mode 100644 index 0000000000..0462f893d5 --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/v0.12.0/_static/img/mascots/scylla-cloud.svg b/v0.12.0/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 0000000000..a6c6a26fc9 --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-cloud.svg @@ -0,0 +1 @@ +scylla-cloud diff --git a/v0.12.0/_static/img/mascots/scylla-computer-3-monsters.png b/v0.12.0/_static/img/mascots/scylla-computer-3-monsters.png new file mode 100644 index 0000000000..d0368a7027 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-computer-3-monsters.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-computer-headset.png b/v0.12.0/_static/img/mascots/scylla-computer-headset.png new file mode 100644 index 0000000000..0cdadaa216 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-computer-headset.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-cup-number-one.png b/v0.12.0/_static/img/mascots/scylla-cup-number-one.png new file mode 100644 index 0000000000..e889f4e368 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-cup-number-one.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-docs.svg b/v0.12.0/_static/img/mascots/scylla-docs.svg new file mode 100644 index 0000000000..a5bce950c2 --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-docs.svg @@ -0,0 +1 @@ +scylla-docs diff --git a/v0.12.0/_static/img/mascots/scylla-drivers.svg b/v0.12.0/_static/img/mascots/scylla-drivers.svg new file mode 100644 index 0000000000..6012e71679 --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-drivers.svg @@ -0,0 +1 @@ +scylla-manager diff --git a/v0.12.0/_static/img/mascots/scylla-enterprise.svg b/v0.12.0/_static/img/mascots/scylla-enterprise.svg new file mode 100644 index 0000000000..a1aa0b46ac --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-enterprise.svg @@ -0,0 +1 @@ +scylla-enterprise diff --git a/v0.12.0/_static/img/mascots/scylla-forklift-boxes.png b/v0.12.0/_static/img/mascots/scylla-forklift-boxes.png new file mode 100644 index 0000000000..f64c29e6c7 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-forklift-boxes.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-forklift-migration.png b/v0.12.0/_static/img/mascots/scylla-forklift-migration.png new file mode 100644 index 0000000000..d2f645c645 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-forklift-migration.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-gear.png b/v0.12.0/_static/img/mascots/scylla-gear.png new file mode 100644 index 0000000000..0f53b26afa Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-gear.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-hardhat.png b/v0.12.0/_static/img/mascots/scylla-hardhat.png new file mode 100644 index 0000000000..630f2d9094 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-hardhat.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-headband.png b/v0.12.0/_static/img/mascots/scylla-headband.png new file mode 100644 index 0000000000..c87abe684d Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-headband.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-headset.png b/v0.12.0/_static/img/mascots/scylla-headset.png new file mode 100644 index 0000000000..ba52cd223d Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-headset.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-hearts.png b/v0.12.0/_static/img/mascots/scylla-hearts.png new file mode 100644 index 0000000000..cef08c8654 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-hearts.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-looking-down.png b/v0.12.0/_static/img/mascots/scylla-looking-down.png new file mode 100644 index 0000000000..75cccbfdf1 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-looking-down.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-looking-up.png b/v0.12.0/_static/img/mascots/scylla-looking-up.png new file mode 100644 index 0000000000..6f10405f21 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-looking-up.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-magnifying-glass-fronting.png b/v0.12.0/_static/img/mascots/scylla-magnifying-glass-fronting.png new file mode 100644 index 0000000000..e368cae169 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-magnifying-glass-fronting.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-magnifying-glass.png b/v0.12.0/_static/img/mascots/scylla-magnifying-glass.png new file mode 100644 index 0000000000..74ad669500 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-magnifying-glass.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-manager.svg b/v0.12.0/_static/img/mascots/scylla-manager.svg new file mode 100644 index 0000000000..6ba9ed937c --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-manager.svg @@ -0,0 +1 @@ +scylla-manager-2 diff --git a/v0.12.0/_static/img/mascots/scylla-monitor.svg b/v0.12.0/_static/img/mascots/scylla-monitor.svg new file mode 100644 index 0000000000..48bec7dde3 --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-monitor.svg @@ -0,0 +1 @@ +scylla-monitor diff --git a/v0.12.0/_static/img/mascots/scylla-movement-fast.png b/v0.12.0/_static/img/mascots/scylla-movement-fast.png new file mode 100644 index 0000000000..956d1dd0e2 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-movement-fast.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-movement.png b/v0.12.0/_static/img/mascots/scylla-movement.png new file mode 100644 index 0000000000..7ee2b04338 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-movement.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-onpremise.png b/v0.12.0/_static/img/mascots/scylla-onpremise.png new file mode 100644 index 0000000000..3b2dc8f1a2 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-onpremise.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-opensource.svg b/v0.12.0/_static/img/mascots/scylla-opensource.svg new file mode 100644 index 0000000000..299e9cb995 --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-opensource.svg @@ -0,0 +1 @@ +Plan de travail 1 diff --git a/v0.12.0/_static/img/mascots/scylla-operator.svg b/v0.12.0/_static/img/mascots/scylla-operator.svg new file mode 100644 index 0000000000..655a450b2a --- /dev/null +++ b/v0.12.0/_static/img/mascots/scylla-operator.svg @@ -0,0 +1 @@ +scylla-operator diff --git a/v0.12.0/_static/img/mascots/scylla-plugin.png b/v0.12.0/_static/img/mascots/scylla-plugin.png new file mode 100644 index 0000000000..b28dc857cc Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-plugin.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-release-mascot.png b/v0.12.0/_static/img/mascots/scylla-release-mascot.png new file mode 100644 index 0000000000..09342ac687 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-release-mascot.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-repair.png b/v0.12.0/_static/img/mascots/scylla-repair.png new file mode 100644 index 0000000000..9b4c613e70 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-repair.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-server.png b/v0.12.0/_static/img/mascots/scylla-server.png new file mode 100644 index 0000000000..96dc785298 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-server.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-sleeping.png b/v0.12.0/_static/img/mascots/scylla-sleeping.png new file mode 100644 index 0000000000..f88598e05a Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-sleeping.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-tall-measure.png b/v0.12.0/_static/img/mascots/scylla-tall-measure.png new file mode 100644 index 0000000000..6f0ca146c0 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-tall-measure.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-university.png b/v0.12.0/_static/img/mascots/scylla-university.png new file mode 100644 index 0000000000..b3d0621193 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-university.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-weights.png b/v0.12.0/_static/img/mascots/scylla-weights.png new file mode 100644 index 0000000000..b070bb022c Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-weights.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-window-cleaning.png b/v0.12.0/_static/img/mascots/scylla-window-cleaning.png new file mode 100644 index 0000000000..6a8b16a6b4 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-window-cleaning.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-with-computer-2.png b/v0.12.0/_static/img/mascots/scylla-with-computer-2.png new file mode 100644 index 0000000000..f3b8b2984f Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-with-computer-2.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-with-computer.png b/v0.12.0/_static/img/mascots/scylla-with-computer.png new file mode 100644 index 0000000000..b38a6fbbe0 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-with-computer.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-with-linux.png b/v0.12.0/_static/img/mascots/scylla-with-linux.png new file mode 100644 index 0000000000..954bf13bc2 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-with-linux.png differ diff --git a/v0.12.0/_static/img/mascots/scylla-writting.png b/v0.12.0/_static/img/mascots/scylla-writting.png new file mode 100644 index 0000000000..d35a13d380 Binary files /dev/null and b/v0.12.0/_static/img/mascots/scylla-writting.png differ diff --git a/v0.12.0/_static/img/menu.svg b/v0.12.0/_static/img/menu.svg new file mode 100644 index 0000000000..30ea1d901e --- /dev/null +++ b/v0.12.0/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/v0.12.0/_static/js/main.bundle.js b/v0.12.0/_static/js/main.bundle.js new file mode 100644 index 0000000000..190a41642e --- /dev/null +++ b/v0.12.0/_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 +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Authentication

          +

          Driver supports both authentication by username and password and custom authentication defined by a user.

          + +
          +

          Custom Authentication

          +

          A custom authentication is defined by implementing the AuthenticatorSession. +An AuthenticatorSession instance is created per session, so it is also necessary to define a AuthenticatorProvider for it. +Finally, to make use of the custom authentication, use the authenticator_provider method in SessionBuilder:

          +
          use bytes::{BufMut, BytesMut};
          +use async_trait::async_trait;
          +use scylla::authentication::{AuthError, AuthenticatorProvider, AuthenticatorSession};
          +
          +struct CustomAuthenticator;
          +
          +#[async_trait]
          +impl AuthenticatorSession for CustomAuthenticator {
          +    // to handle an authentication challenge initiated by the server.
          +    // The information contained in the token parameter is authentication protocol specific.
          +    // It may be NULL or empty. 
          +    async fn evaluate_challenge(
          +        &mut self,
          +        _token: Option<&[u8]>,
          +    ) -> Result<Option<Vec<u8>>, AuthError> {
          +        Err("Challenges are not expected".to_string())
          +    }
          +
          +    // to handle the success phase of exchange. The token parameters contain information that may be used to finalize the request.
          +    async fn success(&mut self, _token: Option<&[u8]>) -> Result<(), AuthError> {
          +        Ok(())
          +    }
          +}
          +
          +struct CustomAuthenticatorProvider;
          +
          +#[async_trait]
          +impl AuthenticatorProvider for CustomAuthenticatorProvider {
          +    async fn start_authentication_session(
          +        &self,
          +        _name: &str,
          +    ) -> Result<(Option<Vec<u8>>, Box<dyn AuthenticatorSession>), AuthError> {
          +        let mut response = BytesMut::new();
          +        let cred = "\0cassandra\0cassandra";
          +        let cred_length = 20;
          +
          +        response.put_i32(cred_length);
          +        response.put_slice(cred.as_bytes());
          +
          +        Ok((Some(response.to_vec()), Box::new(CustomAuthenticator)))
          +    }
          +}
          +
          +async fn authentication_example() -> Result<(), Box<dyn Error>> {
          +    use scylla::{Session, SessionBuilder};
          +
          +    let _session: Session = SessionBuilder::new()
          +        .known_node("127.0.0.1:9042")
          +        .authenticator_provider(Arc::new(CustomAuthenticatorProvider))
          +        .build()
          +        .await?;
          +
          +    Ok(())
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/connecting/compression.html b/v0.12.0/connecting/compression.html new file mode 100644 index 0000000000..8e7cfc2601 --- /dev/null +++ b/v0.12.0/connecting/compression.html @@ -0,0 +1,648 @@ + + + + + + + + + + + + + Compression | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Compression

          +

          By default the driver does not use any compression on connections.
          +It’s possible to specify a preferred compression algorithm.
          +The driver will try using it, but if the database doesn’t support it, it will fall back to no compression.

          +

          Available compression algorithms:

          +
            +
          • Snappy

          • +
          • LZ4

          • +
          +

          An example enabling Snappy compression algorithm:

          +
          use scylla::{Session, SessionBuilder};
          +use scylla::transport::Compression;
          +use std::error::Error;
          +
          +#[tokio::main]
          +async fn main() -> Result<(), Box<dyn Error>> {
          +    let uri = std::env::var("SCYLLA_URI")
          +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
          +
          +    let session: Session = SessionBuilder::new()
          +        .known_node(uri)
          +        .compression(Some(Compression::Snappy))
          +        .build()
          +        .await?;
          +
          +    Ok(())
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/connecting/connecting.html b/v0.12.0/connecting/connecting.html new file mode 100644 index 0000000000..497f9d4ece --- /dev/null +++ b/v0.12.0/connecting/connecting.html @@ -0,0 +1,719 @@ + + + + + + + + + + + + + Connecting to the cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Connecting to the cluster

          +

          Scylla is a distributed database, which means that it operates on multiple nodes running independently. +When creating a Session you can specify a few known nodes to which the driver will try connecting:

          +
          use scylla::{Session, SessionBuilder};
          +use std::error::Error;
          +use std::time::Duration;
          +use std::net::{IpAddr, Ipv4Addr, SocketAddr};
          +
          +#[tokio::main]
          +async fn main() -> Result<(), Box<dyn Error>> {
          +    let uri = std::env::var("SCYLLA_URI")
          +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
          +
          +    let session: Session = SessionBuilder::new()
          +        .known_node(uri)
          +        .known_node("127.0.0.72:4321")
          +        .known_node("localhost:8000")
          +        .connection_timeout(Duration::from_secs(3))
          +        .cluster_metadata_refresh_interval(Duration::from_secs(10))
          +        .known_node_addr(SocketAddr::new(
          +            IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
          +            9000,
          +        ))
          +        .build()
          +        .await?;
          +
          +    Ok(())
          +}
          +
          +
          +

          After successfully connecting to some specified node the driver will fetch topology information about +other nodes in this cluster and connect to them as well.

          +
          +

          Best practices for using Session

          +
          +

          Warning

          +

          Always try to use only a single Session object per apllication because creating them is very expensive!

          +
          +

          The driver maintains its own pool of connections to each node and each connection is capable of handling multiple requests in parallel. Driver will also route requests to nodes / shards that actually own the data (unless the load balancing policy that you use doesn’t support it).

          +

          For those reasons, we recommend using one instance of Session per application.

          +

          Creating short-lived Session’s (e.g. Session per request) is strongly discouraged because it will result in great performance penalties because creating a Session is a costly process - it requires estabilishing a lot of TCP connections. +Creating many Session’s in one application (e.g. Session per thread / per Tokio task) is also discouraged, because it wastes resources - as mentioned before, Session maintains a connection pool itself and can handle parallel queries, so you would be holding a lot of connections unnecessarily.

          +

          If you need to share Session with different threads / Tokio tasks etc. use Arc<Session> - all methods of Session take &self, so it doesn’t hinder the functionality in any way.

          +
          +
          +

          Metadata

          +

          The driver refreshes the cluster metadata periodically, which contains information about cluster topology as well as the cluster schema. By default, the driver refreshes the cluster metadata every 60 seconds. +However, you can set the cluster_metadata_refresh_interval to a non-negative value to periodically refresh the cluster metadata. This is useful when you do not have unexpected amount of traffic or when you have an extra traffic causing topology to change frequently.

          +
          +
          +

          Scylla Cloud Serverless

          +

          Scylla Serverless is an elastic and dynamic deployment model. When creating a Session you need to +specify the secure connection bundle as follows:

          +
          use std::path::Path;
          +use std::error::Error;
          +use scylla::CloudSessionBuilder;
          +
          +#[tokio::main]
          +async fn main() -> Result<(), Box<dyn Error>> {
          +    let session = CloudSessionBuilder::new(Path::new("config_data.yaml"))
          +        .unwrap()
          +        .build()
          +        .await
          +        .unwrap();
          +
          +    Ok(())
          +}
          +
          +
          +

          Note that the bundle file will be provided after the serverless cluster is created. Here is an example of a +configuration file for a serverless cluster:

          +
          datacenters:
          +  datacenter1:
          +    certificateAuthorityData: CERTIFICATE_DATA
          +    server: 127.0.1.1:9142
          +    nodeDomain: cql.cluster-id.scylla.com
          +    insecureSkipTlsVerify: false
          +authInfos:
          +  default:
          +    clientCertificateData: CERTIFICATE_DATA
          +    clientKeyData: KEY_DATA
          +    username: scylladb
          +    password: scylladb
          +contexts:
          +  default:
          +    datacenterName: datacenter1
          +    authInfoName: default
          +currentContext: default
          +
          +
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/connecting/tls.html b/v0.12.0/connecting/tls.html new file mode 100644 index 0000000000..8d6cdd3f29 --- /dev/null +++ b/v0.12.0/connecting/tls.html @@ -0,0 +1,696 @@ + + + + + + + + + + + + + TLS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          TLS

          +

          Driver uses the openssl crate for TLS functionality.
          +It was chosen because rustls doesn’t support certificates for ip addresses +(see issue), which is a common use case for Scylla.

          +
          +

          Enabling feature

          +

          openssl is not a pure Rust library so you need enable a feature and install the proper package.

          +

          To enable the tls feature add in Cargo.toml:

          +
          scylla = { version = "0.4", features = ["ssl"] }
          +openssl = "0.10.32"
          +
          +
          +

          Then install the package with openssl:

          +
            +
          • Debian/Ubuntu:

            +
            apt install libssl-dev pkg-config
            +
            +
            +
          • +
          • Fedora:

            +
            dnf install openssl-devel
            +
            +
            +
          • +
          + +
            +
          • Arch:

            +
            pacman -S openssl pkg-config
            +
            +
            +
          • +
          +
          +
          +

          Using TLS

          +

          To use tls you will have to create an openssl +SslContext +and pass it to SessionBuilder

          +

          For example, if database certificate is in the file ca.crt:

          +
          use scylla::{Session, SessionBuilder};
          +use openssl::ssl::{SslContextBuilder, SslMethod, SslVerifyMode};
          +use std::path::PathBuf;
          +
          +let mut context_builder = SslContextBuilder::new(SslMethod::tls())?;
          +context_builder.set_ca_file("ca.crt")?;
          +context_builder.set_verify(SslVerifyMode::PEER);
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9142") // The the port is now 9142
          +    .ssl_context(Some(context_builder.build()))
          +    .build()
          +    .await?;
          +
          +
          +

          See the full example for more details

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/contents.html b/v0.12.0/contents.html new file mode 100644 index 0000000000..d3ec93d3e1 --- /dev/null +++ b/v0.12.0/contents.html @@ -0,0 +1,609 @@ + + + + + + + + + + + + + <no title> | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/blob.html b/v0.12.0/data-types/blob.html new file mode 100644 index 0000000000..0c25c61b7b --- /dev/null +++ b/v0.12.0/data-types/blob.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Blob | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Blob

          +

          Blob is represented as Vec<u8>

          +
          use scylla::IntoTypedRows;
          +
          +// Insert some blob into the table as a Vec<u8>
          +// We can insert it by reference to not move the whole blob
          +let to_insert: Vec<u8> = vec![1, 2, 3, 4, 5];
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&to_insert,))
          +    .await?;
          +
          +// Read blobs from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(Vec<u8>,)>() {
          +        let (blob_value,): (Vec<u8>,) = row?;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/collections.html b/v0.12.0/data-types/collections.html new file mode 100644 index 0000000000..7d5c168714 --- /dev/null +++ b/v0.12.0/data-types/collections.html @@ -0,0 +1,749 @@ + + + + + + + + + + + + + List, Set, Map | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          List, Set, Map

          +
          +

          List

          +

          List is represented as Vec<T>

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a list of ints into the table
          +let my_list: Vec<i32> = vec![1, 2, 3, 4, 5];
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_list,))
          +    .await?;
          +
          +// Read a list of ints from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(Vec<i32>,)>() {
          +        let (list_value,): (Vec<i32>,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Set

          +

          Set is represented as Vec<T>, HashSet<T> or BTreeSet<T>:

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a set of ints into the table
          +let my_set: Vec<i32> = vec![1, 2, 3, 4, 5];
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
          +    .await?;
          +
          +// Read a set of ints from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(Vec<i32>,)>() {
          +        let (set_value,): (Vec<i32>,) = row?;
          +    }
          +}
          +
          +
          +
          use scylla::IntoTypedRows;
          +use std::collections::HashSet;
          +
          +// Insert a set of ints into the table
          +let my_set: HashSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
          +    .await?;
          +
          +// Read a set of ints from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(HashSet<i32>,)>() {
          +        let (set_value,): (HashSet<i32>,) = row?;
          +    }
          +}
          +
          +
          +
          use scylla::IntoTypedRows;
          +use std::collections::BTreeSet;
          +
          +// Insert a set of ints into the table
          +let my_set: BTreeSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
          +    .await?;
          +
          +// Read a set of ints from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(BTreeSet<i32>,)>() {
          +        let (set_value,): (BTreeSet<i32>,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Map

          +

          Map is represented as HashMap<K, V> or BTreeMap<K, V>

          +
          use scylla::IntoTypedRows;
          +use std::collections::HashMap;
          +
          +// Insert a map of text and int into the table
          +let mut my_map: HashMap<String, i32> = HashMap::new();
          +my_map.insert("abcd".to_string(), 16);
          +
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,))
          +    .await?;
          +
          +// Read a map from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(HashMap<String, i32>,)>() {
          +        let (map_value,): (HashMap<String, i32>,) = row?;
          +    }
          +}
          +
          +
          +
          use scylla::IntoTypedRows;
          +use std::collections::BTreeMap;
          +
          +// Insert a map of text and int into the table
          +let mut my_map: BTreeMap<String, i32> = BTreeMap::new();
          +my_map.insert("abcd".to_string(), 16);
          +
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,))
          +    .await?;
          +
          +// Read a map from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(BTreeMap<String, i32>,)>() {
          +        let (map_value,): (BTreeMap<String, i32>,) = row?;
          +    }
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/counter.html b/v0.12.0/data-types/counter.html new file mode 100644 index 0000000000..9225c6d3e3 --- /dev/null +++ b/v0.12.0/data-types/counter.html @@ -0,0 +1,634 @@ + + + + + + + + + + + + + Counter | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Counter

          +

          Counter is represented as struct Counter(pub i64)
          +Counter can’t be inserted, it can only be read or updated.

          +
          use scylla::IntoTypedRows;
          +use scylla::frame::value::Counter;
          +
          +// Read counter from the table
          +if let Some(rows) = session.query("SELECT c FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(Counter,)>() {
          +        let (counter_value,): (Counter,) = row?;
          +        let counter_int_value: i64 = counter_value.0;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/data-types.html b/v0.12.0/data-types/data-types.html new file mode 100644 index 0000000000..19ce636467 --- /dev/null +++ b/v0.12.0/data-types/data-types.html @@ -0,0 +1,648 @@ + + + + + + + + + + + + + Data Types | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Data Types

          +

          The driver maps database data types to matching Rust types +to achieve seamless sending and receiving of CQL values.

          +

          See the following chapters for examples on how to send and receive each data type.

          +

          See Query values for more information about sending values in queries.
          +See Query result for more information about reading values from queries

          +

          Database types and their Rust equivalents:

          +
            +
          • Boolean <—-> bool

          • +
          • Tinyint <—-> i8

          • +
          • Smallint <—-> i16

          • +
          • Int <—-> i32

          • +
          • BigInt <—-> i64

          • +
          • Float <—-> f32

          • +
          • Double <—-> f64

          • +
          • Ascii, Text, Varchar <—-> &str, String

          • +
          • Counter <—-> value::Counter

          • +
          • Blob <—-> Vec<u8>

          • +
          • Inet <—-> std::net::IpAddr

          • +
          • Uuid <—-> uuid::Uuid

          • +
          • Timeuuid <—-> value::CqlTimeuuid

          • +
          • Date <—-> value::CqlDate, chrono::NaiveDate, time::Date

          • +
          • Time <—-> value::CqlTime, chrono::NaiveTime, time::Time

          • +
          • Timestamp <—-> value::CqlTimestamp, chrono::DateTime<Utc>, time::OffsetDateTime

          • +
          • Duration <—-> value::CqlDuration

          • +
          • Decimal <—-> value::CqlDecimal, bigdecimal::Decimal

          • +
          • Varint <—-> value::CqlVarint, num_bigint::BigInt (v0.3 and v0.4)

          • +
          • List <—-> Vec<T>

          • +
          • Set <—-> Vec<T>

          • +
          • Map <—-> std::collections::HashMap<K, V>

          • +
          • Tuple <—-> Rust tuples

          • +
          • UDT (User defined type) <—-> Custom user structs with macros

          • +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/date.html b/v0.12.0/data-types/date.html new file mode 100644 index 0000000000..eab97e4090 --- /dev/null +++ b/v0.12.0/data-types/date.html @@ -0,0 +1,725 @@ + + + + + + + + + + + + + Date | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Date

          +

          Depending on feature flags, three different types can be used to interact with date.

          +

          Internally date is represented as number of days since +-5877641-06-23 i.e. 2^31 days before unix epoch.

          +
          +

          CqlDate

          +

          Without any extra features enabled, only frame::value::CqlDate is available. It’s an +u32 wrapper and it matches the internal date representation.

          +

          However, for most use cases other types are more practical. See following sections for chrono and time.

          +
          use scylla::frame::value::CqlDate;
          +use scylla::IntoTypedRows;
          +
          +// 1970-01-08
          +let to_insert = CqlDate((1 << 31) + 7);
          +
          +// Insert date into the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read raw Date from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(CqlDate,)>() {
          +        let (date_value,): (CqlDate,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          chrono::NaiveDate

          +

          If full range is not required and chrono feature is enabled, +chrono::NaiveDate can be used. +chrono::NaiveDate supports dates from +-262145-01-01 to 262143-12-31.

          +
          use chrono::NaiveDate;
          +use scylla::IntoTypedRows;
          +
          +// 2021-03-24
          +let to_insert = NaiveDate::from_ymd_opt(2021, 3, 24).unwrap();
          +
          +// Insert date into the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read NaiveDate from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(NaiveDate,)>() {
          +        let (date_value,): (NaiveDate,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          time::Date

          +

          Alternatively, time feature can be used to enable support of +time::Date. +time::Date’s value range depends on feature flags, see its +documentation to get more info.

          +
          use scylla::IntoTypedRows;
          +use time::{Date, Month};
          +
          +// 2021-03-24
          +let to_insert = Date::from_calendar_date(2021, Month::March, 24).unwrap();
          +
          +// Insert date into the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read Date from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(Date,)>() {
          +        let (date_value,): (Date,) = row?;
          +    }
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/decimal.html b/v0.12.0/data-types/decimal.html new file mode 100644 index 0000000000..e9580ace96 --- /dev/null +++ b/v0.12.0/data-types/decimal.html @@ -0,0 +1,678 @@ + + + + + + + + + + + + + Decimal | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Decimal

          +

          Decimal is represented as value::CqlDecimal or bigdecimal::BigDecimal

          +
          +

          value::CqlDecimal

          +

          Without any feature flags, the user can interact with decimal type by making use of value::CqlDecimal which is a very simple wrapper representing the value as signed binary number in big-endian order with a 32-bit scale.

          +
          use scylla::IntoTypedRows;
          +use scylla::frame::value::CqlDecimal;
          +use std::str::FromStr;
          +
          +// Insert a decimal (123.456) into the table
          +let to_insert: CqlDecimal =
          +        CqlDecimal::from_signed_be_bytes_and_exponent(vec![0x01, 0xE2, 0x40], 3);
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a decimal from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(CqlDecimal,)>() {
          +        let (decimal_value,): (CqlDecimal,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          bigdecimal::BigDecimal

          +

          To make use of bigdecimal::Bigdecimal type, user should enable bigdecimal-04 crate feature.

          +
          use scylla::IntoTypedRows;
          +use bigdecimal::BigDecimal;
          +use std::str::FromStr;
          +
          +// Insert a decimal into the table
          +let to_insert: BigDecimal = BigDecimal::from_str("12345.0")?;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a decimal from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(BigDecimal,)>() {
          +        let (decimal_value,): (BigDecimal,) = row?;
          +    }
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/duration.html b/v0.12.0/data-types/duration.html new file mode 100644 index 0000000000..6b25ce9611 --- /dev/null +++ b/v0.12.0/data-types/duration.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Duration | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Duration

          +

          Duration is represented as CqlDuration\

          +
          use scylla::IntoTypedRows;
          +use scylla::frame::value::CqlDuration;
          +
          +// Insert some ip address into the table
          +let to_insert: CqlDuration = CqlDuration { months: 1, days: 2, nanoseconds: 3 };
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read inet from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(CqlDuration,)>() {
          +        let (cql_duration,): (CqlDuration,) = row?;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/inet.html b/v0.12.0/data-types/inet.html new file mode 100644 index 0000000000..d8e6398122 --- /dev/null +++ b/v0.12.0/data-types/inet.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Inet | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Inet

          +

          Inet is represented as std::net::IpAddr

          +
          use scylla::IntoTypedRows;
          +use std::net::{IpAddr, Ipv4Addr};
          +
          +// Insert some ip address into the table
          +let to_insert: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read inet from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(IpAddr,)>() {
          +        let (inet_value,): (IpAddr,) = row?;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/primitive.html b/v0.12.0/data-types/primitive.html new file mode 100644 index 0000000000..a01b8d52b6 --- /dev/null +++ b/v0.12.0/data-types/primitive.html @@ -0,0 +1,777 @@ + + + + + + + + + + + + + Bool, Tinyint, Smallint, Int, Bigint, Float, Double | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Bool, Tinyint, Smallint, Int, Bigint, Float, Double

          +
          +

          Bool

          +

          Bool is represented as rust bool

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a bool into the table
          +let to_insert: bool = true;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a bool from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(bool,)>() {
          +        let (bool_value,): (bool,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Tinyint

          +

          Tinyint is represented as rust i8

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a tinyint into the table
          +let to_insert: i8 = 123;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a tinyint from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(i8,)>() {
          +        let (tinyint_value,): (i8,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Smallint

          +

          Smallint is represented as rust i16

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a smallint into the table
          +let to_insert: i16 = 12345;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a smallint from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(i16,)>() {
          +        let (smallint_value,): (i16,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Int

          +

          Int is represented as rust i32

          +
          use scylla::IntoTypedRows;
          +
          +// Insert an int into the table
          +let to_insert: i32 = 12345;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read an int from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(i32,)>() {
          +        let (int_value,): (i32,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Bigint

          +

          Bigint is represented as rust i64

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a bigint into the table
          +let to_insert: i64 = 12345;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a bigint from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(i64,)>() {
          +        let (bigint_value,): (i64,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Float

          +

          Float is represented as rust f32

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a float into the table
          +let to_insert: f32 = 123.0;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a float from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(f32,)>() {
          +        let (float_value,): (f32,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Double

          +

          Double is represented as rust f64

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a double into the table
          +let to_insert: f64 = 12345.0;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a double from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(f64,)>() {
          +        let (double_value,): (f64,) = row?;
          +    }
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/text.html b/v0.12.0/data-types/text.html new file mode 100644 index 0000000000..49ff69e2b2 --- /dev/null +++ b/v0.12.0/data-types/text.html @@ -0,0 +1,643 @@ + + + + + + + + + + + + + Ascii, Text, Varchar | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Ascii, Text, Varchar

          +

          Ascii, Text and Varchar are represented as &str and String

          +
          use scylla::IntoTypedRows;
          +
          +// Insert some text into the table as a &str
          +let to_insert_str: &str = "abcdef";
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_str,))
          +    .await?;
          +
          +// Insert some text into the table as a String
          +let to_insert_string: String = "abcdef".to_string();
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_string,))
          +    .await?;
          +
          +// Read ascii/text/varchar from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(String,)>() {
          +        let (text_value,): (String,) = row?;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/time.html b/v0.12.0/data-types/time.html new file mode 100644 index 0000000000..11c598e3d1 --- /dev/null +++ b/v0.12.0/data-types/time.html @@ -0,0 +1,723 @@ + + + + + + + + + + + + + Time | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Time

          +

          Depending on feature flags used, three different types can be used to interact with time.

          +

          Internally time is represented as number of nanoseconds since +midnight. It can’t be negative or exceed 86399999999999 (23:59:59.999999999).

          +
          +

          CqlTime

          +

          Without any extra features enabled, only frame::value::CqlTime is available. It’s an +i64 wrapper and it matches the internal time representation.

          +

          However, for most use cases other types are more practical. See following sections for chrono and time.

          +
          use scylla::frame::value::CqlTime;
          +use scylla::IntoTypedRows;
          +
          +// 64 seconds since midnight
          +let to_insert = CqlTime(64 * 1_000_000_000);
          +
          +// Insert time into the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read time from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(CqlTime,)>() {
          +        let (time_value,): (CqlTime,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          chrono::NaiveTime

          +

          If chrono feature is enabled, chrono::NaiveTime +can be used to interact with the database. Although chrono can represent leap seconds, they are not supported. +Attempts to convert chrono::NaiveTime with leap +second to CqlTime or write it to the database will return an error.

          +
          use chrono::NaiveTime;
          +use scylla::IntoTypedRows;
          +
          +// 01:02:03.456,789,012
          +let to_insert = NaiveTime::from_hms_nano_opt(1, 2, 3, 456_789_012);
          +
          +// Insert time into the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read time from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(NaiveTime,)>() {
          +        let (time_value,): (NaiveTime,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          time::Time

          +

          If time feature is enabled, time::Time can be used to interact +with the database.

          +
          use scylla::IntoTypedRows;
          +use time::Time;
          +
          +// 01:02:03.456,789,012
          +let to_insert = Time::from_hms_nano(1, 2, 3, 456_789_012).unwrap();
          +
          +// Insert time into the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read time from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(Time,)>() {
          +        let (time_value,): (Time,) = row?;
          +    }
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/timestamp.html b/v0.12.0/data-types/timestamp.html new file mode 100644 index 0000000000..409567534f --- /dev/null +++ b/v0.12.0/data-types/timestamp.html @@ -0,0 +1,735 @@ + + + + + + + + + + + + + Timestamp | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Timestamp

          +

          Depending on feature flags, three different types can be used to interact with timestamps.

          +

          Internally timestamp is represented as +i64 describing number of milliseconds since unix epoch.

          +
          +

          CqlTimestamp

          +

          Without any extra features enabled, only frame::value::CqlTimestamp is available. It’s an +i64 wrapper and it matches the internal time representation. It’s +the only type that supports full range of values that database accepts.

          +

          However, for most use cases other types are more practical. See following sections for chrono and time.

          +
          use scylla::frame::value::CqlTimestamp;
          +use scylla::IntoTypedRows;
          +
          +// 64 seconds since unix epoch, 1970-01-01 00:01:04
          +let to_insert = CqlTimestamp(64 * 1000);
          +
          +// Write timestamp to the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read timestamp from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(CqlTimestamp,)>() {
          +        let (timestamp_value,): (CqlTimestamp,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          chrono::DateTime

          +

          If full value range is not required, chrono feature can be used to enable support of +chrono::DateTime. All values are expected to be converted +to UTC timezone explicitly, as timestamp doesn’t store +timezone information. Any precision finer than 1ms will be lost.

          +
          use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
          +use scylla::IntoTypedRows;
          +
          +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123
          +let to_insert = NaiveDateTime::new(
          +    NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(),
          +    NaiveTime::from_hms_milli_opt(0, 1, 4, 123).unwrap(),
          +)
          +.and_utc();
          +
          +// Write timestamp to the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read timestamp from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(DateTime<Utc>,)>() {
          +        let (timestamp_value,): (DateTime<Utc>,) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          time::OffsetDateTime

          +

          Alternatively, time feature can be used to enable support of +time::OffsetDateTime. As +timestamp doesn’t support timezone information, time will +be corrected to UTC and timezone info will be erased on write. On read, UTC timestamp is returned. Any precision finer +than 1ms will also be lost.

          +
          use scylla::IntoTypedRows;
          +use time::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time};
          +
          +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123
          +let to_insert = PrimitiveDateTime::new(
          +    Date::from_calendar_date(1970, Month::January, 1).unwrap(),
          +    Time::from_hms_milli(0, 1, 4, 123).unwrap(),
          +)
          +.assume_utc();
          +
          +// Write timestamp to the table
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read timestamp from the table
          +if let Some(rows) = session
          +    .query("SELECT a FROM keyspace.table", &[])
          +    .await?
          +    .rows
          +{
          +    for row in rows.into_typed::<(OffsetDateTime,)>() {
          +        let (timestamp_value,): (OffsetDateTime,) = row?;
          +    }
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/timeuuid.html b/v0.12.0/data-types/timeuuid.html new file mode 100644 index 0000000000..4fa6d3dc85 --- /dev/null +++ b/v0.12.0/data-types/timeuuid.html @@ -0,0 +1,640 @@ + + + + + + + + + + + + + Timeuuid | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Timeuuid

          +

          Timeuuid is represented as value::CqlTimeuuid. +value::CqlTimeuuid is a wrapper for uuid::Uuid with custom ordering logic +which follows Scylla/Cassandra semantics.

          +
          use scylla::IntoTypedRows;
          +use scylla::frame::value::CqlTimeuuid;
          +
          +// Insert some timeuuid into the table
          +let to_insert: CqlTimeuuid = CqlTimeuuid::from_str("8e14e760-7fa8-11eb-bc66-000000000001")?;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read timeuuid from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(CqlTimeuuid,)>() {
          +        let (timeuuid_value,): (CqlTimeuuid,) = row?;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/tuple.html b/v0.12.0/data-types/tuple.html new file mode 100644 index 0000000000..6cf71cb5e8 --- /dev/null +++ b/v0.12.0/data-types/tuple.html @@ -0,0 +1,640 @@ + + + + + + + + + + + + + Tuple | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Tuple

          +

          Tuple is represented as rust tuples of max 16 elements.

          +
          use scylla::IntoTypedRows;
          +
          +// Insert a tuple of int and string into the table
          +let to_insert: (i32, String) = (1, "abc".to_string());
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a tuple of int and string from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<((i32, String),)>() {
          +        let (tuple_value,): ((i32, String),) = row?;
          +
          +        let int_value: i32 = tuple_value.0;
          +        let string_value: String = tuple_value.1;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/udt.html b/v0.12.0/data-types/udt.html new file mode 100644 index 0000000000..a669cd94c6 --- /dev/null +++ b/v0.12.0/data-types/udt.html @@ -0,0 +1,689 @@ + + + + + + + + + + + + + User defined types | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          User defined types

          +

          Scylla allows users to define their own data types with named fields (See the official documentation)
          +To use user defined types in the driver, you can create a corresponding struct in Rust, and use it to read and write UDT values.

          +

          For example let’s say my_type was created using this query:

          +
          CREATE TYPE ks.my_type (int_val int, text_val text)
          +
          +
          +

          To use this type in the driver, create a matching struct and derive:

          +
            +
          • SerializeCql: in order to be able to use this struct in query parameters.
            +This macro requires fields of UDT and struct to have matching names, but the order +of the fields is not required to be the same.
            +Note: you can use different name using rename attribute - see SerializeCql macro documentation.

          • +
          • FromUserType: in order to be able to use this struct in query results.
            +This macro requires fields of UDT and struct to be in the same ORDER.
            +This mismatch between SerializeCql and FromUserType requirements is a temporary situation - in the future FromUserType (or the macro that replaces it) will also require matching names.

          • +
          +
          use scylla::macros::{FromUserType, SerializeCql};
          +
          +// Define a custom struct that matches the User Defined Type created earlier.
          +// Fields must be in the same order as they are in the database and also
          +// have the same names.
          +// Wrapping a field in Option will gracefully handle null field values.
          +#[derive(Debug, FromUserType, SerializeCql)]
          +struct MyType {
          +    int_val: i32,
          +    text_val: Option<String>,
          +}
          +
          +
          +
          +

          Important
          +For deserialization, fields in the Rust struct must be defined in the same order as they are in the database. +When receiving values, the driver will (de)serialize fields one after another, without looking at field names.

          +
          +
          +

          Important
          +For serialization, by default fields in the Rust struct must be defined with the same names as they are in the database. +The driver will serialize the fields in the order defined by the UDT, matching Rust fields by name. +You can change this behaviour using macro attributes, see SerializeCql macro documentation for more information.

          +
          +

          Now it can be sent and received just like any other CQL value:

          +
          use scylla::IntoTypedRows;
          +use scylla::macros::{FromUserType, SerializeCql};
          +use scylla::cql_to_rust::FromCqlVal;
          +
          +#[derive(Debug, FromUserType, SerializeCql)]
          +struct MyType {
          +    int_val: i32,
          +    text_val: Option<String>,
          +}
          +
          +// Insert my_type into the table
          +let to_insert = MyType {
          +    int_val: 17,
          +    text_val: Some("Some string".to_string()),
          +};
          +
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read MyType from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(MyType,)>() {
          +        let (my_type_value,): (MyType,) = row?;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/uuid.html b/v0.12.0/data-types/uuid.html new file mode 100644 index 0000000000..2723b9af5d --- /dev/null +++ b/v0.12.0/data-types/uuid.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Uuid | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Uuid

          +

          Uuid is represented as uuid::Uuid.

          +
          use scylla::IntoTypedRows;
          +use uuid::Uuid;
          +
          +// Insert some uuid into the table
          +let to_insert: Uuid = Uuid::parse_str("8e14e760-7fa8-11eb-bc66-000000000001")?;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read uuid from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(Uuid,)>() {
          +        let (uuid_value,): (Uuid,) = row?;
          +    }
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/data-types/varint.html b/v0.12.0/data-types/varint.html new file mode 100644 index 0000000000..7f012ff30b --- /dev/null +++ b/v0.12.0/data-types/varint.html @@ -0,0 +1,664 @@ + + + + + + + + + + + + + Varint | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Varint

          +

          Varint is represented as value::CqlVarint or num_bigint::BigInt.

          +
          +

          num_bigint::BigInt

          +

          To make use of num_bigint::BigInt type, user should enable one of the available feature flags (num-bigint-03 or num-bigint-04). They enable support for num_bigint::BigInt v0.3 and v0.4 accordingly.

          +
          +
          +

          value::CqlVarint

          +

          Without any feature flags, the user can interact with Varint type by making use of value::CqlVarint which +is a very simple wrapper representing the value as signed binary number in big-endian order.

          +
          +
          +

          Example

          +
          use scylla::IntoTypedRows;
          +use num_bigint::BigInt;
          +use std::str::FromStr;
          +
          +// Insert a varint into the table
          +let to_insert: BigInt = BigInt::from_str("12345")?;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +// Read a varint from the table
          +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
          +    for row in rows.into_typed::<(BigInt,)>() {
          +        let (varint_value,): (BigInt,) = row?;
          +    }
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/execution-profiles/create-and-use.html b/v0.12.0/execution-profiles/create-and-use.html new file mode 100644 index 0000000000..b6900730b4 --- /dev/null +++ b/v0.12.0/execution-profiles/create-and-use.html @@ -0,0 +1,695 @@ + + + + + + + + + + + + + Creating a profile and setting it | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Creating a profile and setting it

          +
          +

          Example

          +

          To create an ExecutionProfile and attach it as default for Session:

          +
          use scylla::{Session, SessionBuilder};
          +use scylla::statement::Consistency;
          +use scylla::transport::ExecutionProfile;
          +
          +let profile = ExecutionProfile::builder()
          +    .consistency(Consistency::LocalOne)
          +    .request_timeout(None) // no request timeout
          +    .build();
          +
          +let handle = profile.into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .default_execution_profile_handle(handle)
          +    .build()
          +    .await?;
          +
          +
          +
          +
          +

          Example

          +

          To create an ExecutionProfile and attach it to a Query:

          +
          use scylla::query::Query;
          +use scylla::statement::Consistency;
          +use scylla::transport::ExecutionProfile;
          +use std::time::Duration;
          +
          +let profile = ExecutionProfile::builder()
          +    .consistency(Consistency::All)
          +    .request_timeout(Some(Duration::from_secs(30)))
          +    .build();
          +
          +let handle = profile.into_handle();
          +
          +let mut query1 = Query::from("SELECT * FROM ks.table");
          +query1.set_execution_profile_handle(Some(handle.clone()));
          +
          +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?");
          +query2.set_execution_profile_handle(Some(handle));
          +
          +
          +
          +
          +

          Example

          +

          To create an ExecutionProfile based on another profile:

          +
          use scylla::statement::Consistency;
          +use scylla::transport::ExecutionProfile;
          +use std::time::Duration;
          +
          +let base_profile = ExecutionProfile::builder()
          +    .request_timeout(Some(Duration::from_secs(30)))
          +    .build();
          +
          +let profile = base_profile.to_builder()
          +    .consistency(Consistency::All)
          +    .build();
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/execution-profiles/execution-profiles.html b/v0.12.0/execution-profiles/execution-profiles.html new file mode 100644 index 0000000000..36e5fba08b --- /dev/null +++ b/v0.12.0/execution-profiles/execution-profiles.html @@ -0,0 +1,629 @@ + + + + + + + + + + + + + Execution profiles | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Execution profiles

          +

          Execution profiles are a way to group various query execution configuration options together. Profiles can be created to represent different workloads, which can be run conveniently on a single session.

          +

          The settings that an execution profile encapsulates are as follows:

          +
            +
          • consistency

          • +
          • serial consistency

          • +
          • request timeout

          • +
          • load balancing policy

          • +
          • retry policy

          • +
          • speculative execution policy

          • +
          +

          There are two classes of objects related to execution profiles: ExecutionProfile and ExecutionProfileHandle. The former is simply an immutable set of the settings. The latter is a handle that at particular moment points to some ExecutionProfile (but during its lifetime, it can change the profile it points at). Handles are assigned to Sessions and Statements.
          +
          +At any moment, handles can be remapped to point to another ExecutionProfile. This allows convenient switching between workloads for all Sessions and/or Statements that, for instance, share common characteristics.

          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/execution-profiles/maximal-example.html b/v0.12.0/execution-profiles/maximal-example.html new file mode 100644 index 0000000000..087fa4d78e --- /dev/null +++ b/v0.12.0/execution-profiles/maximal-example.html @@ -0,0 +1,665 @@ + + + + + + + + + + + + + All options supported by a profile | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          All options supported by a profile

          +
          +

          Example

          +

          ExecutionProfile supports all the following options:

          +
          use scylla::query::Query;
          +use scylla::speculative_execution::SimpleSpeculativeExecutionPolicy;
          +use scylla::statement::{Consistency, SerialConsistency};
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::load_balancing::DefaultPolicy;
          +use scylla::transport::retry_policy::FallthroughRetryPolicy;
          +use std::{sync::Arc, time::Duration};
          +
          +let profile = ExecutionProfile::builder()
          +    .consistency(Consistency::All)
          +    .serial_consistency(Some(SerialConsistency::Serial))
          +    .request_timeout(Some(Duration::from_secs(30)))
          +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
          +    .load_balancing_policy(Arc::new(DefaultPolicy::default()))
          +    .speculative_execution_policy(
          +        Some(
          +            Arc::new(
          +                SimpleSpeculativeExecutionPolicy {
          +                    max_retry_count: 3,
          +                    retry_interval: Duration::from_millis(100),
          +                }
          +            )
          +        )
          +    )
          +    .build();
          +
          +let mut query = Query::from("SELECT * FROM ks.table");
          +query.set_execution_profile_handle(Some(profile.into_handle()));
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/execution-profiles/priority.html b/v0.12.0/execution-profiles/priority.html new file mode 100644 index 0000000000..6557dae2cd --- /dev/null +++ b/v0.12.0/execution-profiles/priority.html @@ -0,0 +1,677 @@ + + + + + + + + + + + + + Priorities of execution settings | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Priorities of execution settings

          +

          You always have a default execution profile set for the Session, either the default one or overridden upon Session creation. Moreover, you can set a profile for specific statements, in which case the statement’s profile has higher priority. Some options are also available for specific statements to be set directly on them, such as request timeout and consistency. In such case, the directly set options are preferred over those specified in execution profiles.

          +
          +

          Recap
          +Priorities are as follows:
          +Session’s default profile < Statement’s profile < options set directly on a Statement

          +
          +
          +

          Example

          +

          Priorities of execution profiles and directly set options:

          +
          use scylla::{Session, SessionBuilder};
          +use scylla::query::Query;
          +use scylla::statement::Consistency;
          +use scylla::transport::ExecutionProfile;
          +
          +let session_profile = ExecutionProfile::builder()
          +    .consistency(Consistency::One)
          +    .build();
          +
          +let query_profile = ExecutionProfile::builder()
          +    .consistency(Consistency::Two)
          +    .build();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .default_execution_profile_handle(session_profile.into_handle())
          +    .build()
          +    .await?;
          +
          +let mut query = Query::from("SELECT * FROM ks.table");
          +
          +// Query is not assigned any specific profile, so session's profile is applied.
          +// Therefore, the query will be executed with Consistency::One.
          +session.query(query.clone(), ()).await?;
          +
          +query.set_execution_profile_handle(Some(query_profile.into_handle()));
          +// Query's profile is applied.
          +// Therefore, the query will be executed with Consistency::Two.
          +session.query(query.clone(), ()).await?;
          +
          +query.set_consistency(Consistency::Three);
          +// An option is set directly on the query.
          +// Therefore, the query will be executed with Consistency::Three.
          +session.query(query, ()).await?;
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/execution-profiles/remap.html b/v0.12.0/execution-profiles/remap.html new file mode 100644 index 0000000000..d52d6a3f30 --- /dev/null +++ b/v0.12.0/execution-profiles/remap.html @@ -0,0 +1,700 @@ + + + + + + + + + + + + + Remapping execution profile handles | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Remapping execution profile handles

          +

          ExecutionProfileHandles can be remapped to another ExecutionProfile, and the change affects all sessions and statements that have been assigned that handle. This enables quick workload switches.

          +

          Example mapping:

          +
            +
          • session1 -> handle1 -> profile1

          • +
          • statement1 -> handle1 -> profile1

          • +
          • statement2 -> handle2 -> profile2

          • +
          +

          We can now remap handle2 to profile1, so that the mapping for statement2 becomes as follows:

          +
            +
          • statement2 -> handle2 -> profile1

          • +
          +

          We can also change statement1’s handle to handle2, and remap handle1 to profile2, yielding:

          +
            +
          • session1 -> handle1 -> profile2

          • +
          • statement1 -> handle2 -> profile1

          • +
          • statement2 -> handle2 -> profile1

          • +
          +

          As you can see, profiles are a powerful and convenient way to define and modify your workloads.

          +
          +

          Example

          +

          Below, the remaps described above are followed in code.

          +
          use scylla::{Session, SessionBuilder};
          +use scylla::query::Query;
          +use scylla::statement::Consistency;
          +use scylla::transport::ExecutionProfile;
          +
          +let profile1 = ExecutionProfile::builder()
          +    .consistency(Consistency::One)
          +    .build();
          +
          +let profile2 = ExecutionProfile::builder()
          +    .consistency(Consistency::Two)
          +    .build();
          +
          +let mut handle1 = profile1.clone().into_handle();
          +let mut handle2 = profile2.clone().into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .default_execution_profile_handle(handle1.clone())
          +    .build()
          +    .await?;
          +
          +let mut query1 = Query::from("SELECT * FROM ks.table");
          +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?");
          +
          +query1.set_execution_profile_handle(Some(handle1.clone()));
          +query2.set_execution_profile_handle(Some(handle2.clone()));
          +
          +// session1 -> handle1 -> profile1
          +// query1 -> handle1 -> profile1
          +// query2 -> handle2 -> profile2
          +
          +// We can now remap handle2 to profile1:
          +handle2.map_to_another_profile(profile1);
          +// ...so that the mapping for query2 becomes as follows:
          +// query2 -> handle2 -> profile1
          +
          +// We can also change query1's handle to handle2:
          +query1.set_execution_profile_handle(Some(handle2.clone()));
          +// ...and remap handle1 to profile2:
          +handle1.map_to_another_profile(profile2);
          +// ...yielding:
          +// session1 -> handle1 -> profile2
          +// query1 -> handle2 -> profile1
          +// query2 -> handle2 -> profile1
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/genindex.html b/v0.12.0/genindex.html new file mode 100644 index 0000000000..16de99643c --- /dev/null +++ b/v0.12.0/genindex.html @@ -0,0 +1,595 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + + + +
          + + + + + +
          + + +
          + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/index.html b/v0.12.0/index.html new file mode 100644 index 0000000000..27fb7adda6 --- /dev/null +++ b/v0.12.0/index.html @@ -0,0 +1,646 @@ + + + + + + + + + + + + + Scylla Rust Driver | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Scylla Rust Driver

          +

          This book contains documentation for scylla-rust-driver - a driver +for the Scylla database written in Rust. +Although optimized for Scylla, the driver is also compatible with Apache Cassandra®.

          +
          +

          Other documentation

          + +
          +
          +

          Contents

          + +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/load-balancing/default-policy.html b/v0.12.0/load-balancing/default-policy.html new file mode 100644 index 0000000000..afbd6e1342 --- /dev/null +++ b/v0.12.0/load-balancing/default-policy.html @@ -0,0 +1,802 @@ + + + + + + + + + + + + + DefaultPolicy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          DefaultPolicy

          +

          DefaultPolicy is the default load balancing policy in Scylla Rust Driver. It +can be configured to be datacenter-aware and token-aware. Datacenter failover +for queries with non-local consistency mode is also supported.

          +
          +

          Creating a DefaultPolicy

          +

          DefaultPolicy can be created only using DefaultPolicyBuilder. The +builder() method of DefaultPolicy returns a new instance of +DefaultPolicyBuilder with the following default values:

          +
            +
          • preferences: no particular datacenter/rack preference

          • +
          • is_token_aware: true

          • +
          • permit_dc_failover: false

          • +
          • latency_awareness: None

          • +
          +

          You can use the builder methods to configure the desired settings and create a +DefaultPolicy instance:

          +
          use scylla::load_balancing::DefaultPolicy;
          +
          +let default_policy = DefaultPolicy::builder()
          +        .prefer_datacenter_and_rack("dc1".to_string(), "rack1".to_string())
          +        .token_aware(true)
          +        .permit_dc_failover(true)
          +        .build();
          +
          +
          +
          +

          Semantics of DefaultPolicy

          +
          +

          Preferences

          +

          The preferences field in DefaultPolicy allows the load balancing +policy to prioritize nodes based on their location. It has three modes:

          +
            +
          • no preference

          • +
          • preferred datacenter

          • +
          • preferred datacenter and rack

          • +
          +

          When a datacenter "my_dc" is preferred, the policy will treat nodes in "my_dc" +as “local” nodes, and nodes in other datacenters as “remote” nodes. This affects +the order in which nodes are returned by the policy when selecting nodes for +read or write operations. If no datacenter is preferred, the policy will treat +all nodes as local nodes.

          +

          preferences allow the load balancing policy to prioritize nodes based on their +availability zones (racks) in the preferred datacenter, too. When a datacenter +and a rack are preferred, the policy will first return replicas in the local rack +in the preferred datacenter, and then the other replicas in the datacenter +(followed by remote replicas). After replicas, the other node will be ordered +similarly, too (local rack nodes, local datacenter nodes, remote nodes).

          +

          When datacenter failover is disabled (permit_dc_failover is set to +false), the default policy will only include local nodes in load balancing +plans. Remote nodes will be excluded, even if they are alive and available to +serve requests.

          +
          +
          +

          Datacenter Failover

          +

          In the event of a datacenter outage or network failure, the nodes in that +datacenter may become unavailable, and clients may no longer be able to access +the data stored on those nodes. To address this, the DefaultPolicy supports +datacenter failover, which allows to route requests to nodes in other datacenters +if the local nodes are unavailable.

          +

          Datacenter failover can be enabled in DefaultPolicy by permit_dc_failover +setting in the builder. When this flag is set, the policy will prefer to return +alive remote replicas if datacenter failover is permitted and possible due to +consistency constraints.

          +
          +
          +

          Token awareness

          +

          Token awareness refers to a mechanism by which the driver is aware of the token +range assigned to each node in the cluster. Tokens are assigned to nodes to +partition the data and distribute it across the cluster.

          +

          When a user wants to read or write data, the driver can use token awareness to +route the request to the correct node based on the token range of the data +being accessed. This can help to minimize network traffic and improve +performance by ensuring that the data is accessed locally as much as possible.

          +

          In the case of DefaultPolicy, token awareness is enabled by default, meaning +that the policy will prefer to return alive local replicas if the token is +available. This means that if the client is requesting data that falls within +the token range of a particular node, the policy will try to route the request +to that node first, assuming it is alive and responsive.

          +

          Token awareness can significantly improve the performance and scalability of +applications built on Scylla. By using token awareness, users can ensure that +data is accessed locally as much as possible, reducing network overhead and +improving throughput.

          +

          Please note that for token awareness to be applied, a statement must be +prepared before being executed.

          +
          +
          +
          +

          Latency awareness

          +

          Latency awareness is a mechanism that penalises nodes whose measured recent +average latency classifies it as falling behind the others.

          +

          Every update_rate the global minimum average latency is computed, +and all nodes whose average latency is worse than exclusion_threshold +times the global minimum average latency become penalised for +retry_period. Penalisation involves putting those nodes at the very end +of the query plan. As it is often not truly beneficial to prefer +faster non-replica than replicas lagging behind the non-replicas, +this mechanism may as well worsen latencies and/or throughput.

          +
          +

          Warning

          +

          Using latency awareness is NOT recommended, unless prior +benchmarks prove its beneficial impact on the specific workload’s +performance. Use with caution.

          +
          +
          +
          +

          Creating a latency aware DefaultPolicy

          +
          use scylla::load_balancing::{
          +    LatencyAwarenessBuilder, DefaultPolicy
          +};
          +use std::time::Duration;
          +
          +let latency_awareness_builder = LatencyAwarenessBuilder::new()
          +    .exclusion_threshold(3.)
          +    .update_rate(Duration::from_secs(3))
          +    .retry_period(Duration::from_secs(30))
          +    .minimum_measurements(200);
          +
          +let policy = DefaultPolicy::builder()
          +        // Here further customisation is, of course, possible.
          +        // e.g.: .prefer_datacenter(...)
          +        .latency_awareness(latency_awareness_builder)
          +        .build();
          +
          +
          +
          use scylla::load_balancing::DefaultPolicy;
          +
          +let default_policy = DefaultPolicy::builder()
          +        .prefer_datacenter("dc1".to_string())
          +        .token_aware(true)
          +        .permit_dc_failover(true)
          +        .build();
          +
          +
          +
          +
          +

          Node order in produced plans

          +

          The DefaultPolicy prefers to return nodes in the following order:

          +
            +
          1. Alive local replicas (if token is available & token awareness is enabled)

          2. +
          3. Alive remote replicas (if datacenter failover is permitted & possible due to consistency constraints)

          4. +
          5. Alive local nodes

          6. +
          7. Alive remote nodes (if datacenter failover is permitted & possible due to consistency constraints)

          8. +
          9. Enabled down nodes +And only if latency awareness is enabled:

          10. +
          11. Penalised: alive local replicas, alive remote replicas, … (in order as above).

          12. +
          +

          If no preferred datacenter is specified, all nodes are treated as local ones.

          +

          Replicas in the same priority groups are shuffled[1]. Non-replicas are randomly +rotated (similarly to a round robin with a random index).

          +
          + +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/load-balancing/load-balancing.html b/v0.12.0/load-balancing/load-balancing.html new file mode 100644 index 0000000000..1ea11b1b34 --- /dev/null +++ b/v0.12.0/load-balancing/load-balancing.html @@ -0,0 +1,736 @@ + + + + + + + + + + + + + Load balancing | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Load balancing

          +
          +

          Introduction

          +

          The driver uses a load balancing policy to determine which node(s) to contact +when executing a query. Load balancing policies implement the +LoadBalancingPolicy trait, which contains methods to generate a load +balancing plan based on the query information and the state of the cluster.

          +

          Load balancing policies do not influence to which nodes connections are +being opened. For a node connection blacklist configuration refer to +scylla::transport::host_filter::HostFilter, which can be set session-wide +using SessionBuilder::host_filter method.

          +
          +
          +

          Plan

          +

          When a query is prepared to be sent to the database, the load balancing policy +constructs a load balancing plan. This plan is essentially a list of nodes to +which the driver will try to send the query. The first elements of the plan are +the nodes which are the best to contact (e.g. they might be replicas for the +requested data or have the best latency).

          +
          +
          +

          Policy

          +

          The Scylla/Cassandra driver provides a default load balancing policy (see +Default Policy for details), but you can +also implement your own custom policies that better suit your specific use +case. To use a custom policy, you simply need to implement the +LoadBalancingPolicy trait and pass an instance of your custom policy to the +used execution profile.

          +

          Our recommendation is to use Default Policy with token- +awareness enabled and latency-awareness disabled.

          +
          +
          +

          Configuration

          +

          Load balancing policies can be configured via execution profiles. In the code +sample provided, a new execution profile is created using +ExecutionProfile::builder(), and the load balancing policy is set to the +DefaultPolicy using .load_balancing_policy(policy).

          +

          The newly created execution profile is then converted to a handle using +.into_handle(), and passed as the default execution profile to the +SessionBuilder using .default_execution_profile_handle(handle).

          +
          use scylla::SessionBuilder;
          +use scylla::load_balancing::DefaultPolicy;
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::session::Session;
          +use std::sync::Arc;
          +
          +let policy = Arc::new(DefaultPolicy::default());
          +
          +let profile = ExecutionProfile::builder()
          +    .load_balancing_policy(policy)
          +    .build();
          +let handle = profile.into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node(&uri)
          +    .default_execution_profile_handle(handle)
          +    .build()
          +    .await?;
          +
          +
          +

          In addition to being able to configure load balancing policies through +execution profiles at the session level, the driver also allow for setting +execution profile handles on a per-query basis. This means that for each query, +a specific execution profile can be selected with a customized load balancing +settings.

          +
          +
          +

          LoadBalancingPolicy trait

          +
          +

          pick and fallback:

          +

          Most queries are sent successfully on the first try. In such cases, only the +first element of the load balancing plan is needed, so it’s usually unnecessary +to compute entire load balancing plan. To optimize this common case, the +LoadBalancingPolicy trait provides two methods: pick and fallback.

          +

          pick returns the first node to contact for a given query, which is usually +the best based on a particular load balancing policy. If pick returns None, +then fallback will not be called.

          +

          fallback, returns an iterator that provides the rest of the nodes in the load +balancing plan. fallback is called only when using the initial picked node +fails (or when executing speculatively).

          +

          It’s possible for the fallback method to include the same node that was +returned by the pick method. In such cases, the query execution layer filters +out the picked node from the iterator returned by fallback.

          +
          +
          +

          on_query_success and on_query_failure:

          +

          The on_query_success and on_query_failure methods are useful for load +balancing policies because they provide feedback on the performance and health +of the nodes in the cluster.

          +

          When a query is successfully executed, the on_query_success method is called +and can be used by the load balancing policy to update its internal state. For +example, a policy might use the latency of the successful query to update its +latency statistics for each node in the cluster. This information can be used +to make decisions about which nodes to contact in the future.

          +

          On the other hand, when a query fails to execute, the on_query_failure method +is called and provides information about the failure. The error message +returned by Cassandra can help determine the cause of the failure, such as a +node being down or overloaded. The load balancing policy can use this +information to update its internal state and avoid contacting the same node +again until it’s recovered.

          +
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/logging/logging.html b/v0.12.0/logging/logging.html new file mode 100644 index 0000000000..6e8974cea2 --- /dev/null +++ b/v0.12.0/logging/logging.html @@ -0,0 +1,651 @@ + + + + + + + + + + + + + Logging | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Logging

          +

          The driver uses the tracing crate for all logs.
          +To view the logs you have to create a tracing subscriber to which all logs will be written.

          +

          To just print the logs you can use the default subscriber:

          +
          use tracing::info;
          +
          +#[tokio::main]
          +async fn main() -> Result<(), Box<dyn Error>> {
          +    // Install global collector configured based on RUST_LOG env var
          +    // This collector will receive logs from the driver
          +    tracing_subscriber::fmt::init();
          +
          +    let uri = std::env::var("SCYLLA_URI")
          +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
          +
          +    info!("Connecting to {}", uri);
          +
          +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
          +    session
          +        .query(
          +            "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \
          +            {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}",
          +            &[],
          +        )
          +        .await?;
          +
          +    // This query should generate a warning message
          +    session.query("USE ks", &[]).await?;
          +
          +    Ok(())
          +}
          +
          +
          +

          To start this example execute:

          +
          RUST_LOG=info cargo run
          +
          +
          +

          The full example is available in the examples folder

          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/metrics/metrics.html b/v0.12.0/metrics/metrics.html new file mode 100644 index 0000000000..5a58242603 --- /dev/null +++ b/v0.12.0/metrics/metrics.html @@ -0,0 +1,655 @@ + + + + + + + + + + + + + Driver metrics | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Driver metrics

          +

          During operation the driver collects various metrics.

          +

          They can be accessed at any moment using Session::get_metrics()

          +
          +

          Collected metrics:

          +
            +
          • Query latencies

          • +
          • Total number of nonpaged queries

          • +
          • Number of errors during nonpaged queries

          • +
          • Total number of paged queries

          • +
          • Number of errors during paged queries

          • +
          • Number of retries

          • +
          +
          +
          +

          Example

          +
          let metrics = session.get_metrics();
          +
          +println!("Queries requested: {}", metrics.get_queries_num());
          +println!("Iter queries requested: {}", metrics.get_queries_iter_num());
          +println!("Errors occurred: {}", metrics.get_errors_num());
          +println!("Iter errors occurred: {}", metrics.get_errors_iter_num());
          +println!("Average latency: {}", metrics.get_latency_avg_ms().unwrap());
          +println!(
          +    "99.9 latency percentile: {}",
          +    metrics.get_latency_percentile_ms(99.9).unwrap()
          +);
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/migration-guides/0.11-serialization.html b/v0.12.0/migration-guides/0.11-serialization.html new file mode 100644 index 0000000000..bfc1969e86 --- /dev/null +++ b/v0.12.0/migration-guides/0.11-serialization.html @@ -0,0 +1,733 @@ + + + + + + + + + + + + + Adjusting code to changes in serialization API introduced in 0.11 | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Adjusting code to changes in serialization API introduced in 0.11

          +
          +

          Background

          +

          When executing a statement through the CQL protocol, values for the bind markers are sent in a serialized, untyped form. In order to implement a safer and more robust interface, drivers can use the information returned after preparing a statement to check the type of data provided by the user against the actual types of the bind markers.

          +

          Before 0.11, the driver couldn’t do this kind of type checking. For example, in the case of non-batch queries, the only information about the user data it has is that it implements ValueList - defined as follows:

          +
          pub trait ValueList {
          +    fn serialized(&self) -> SerializedResult<'_>;
          +    fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError>;
          +}
          +
          +
          +

          The driver would naively serialize the data and hope that the user took care to send correct types of values. Failing to do so would, in the best case, fail on the DB-side validation; in the worst case, the data in its raw form may be reinterpreted as another type in an unintended manner.

          +

          Another problem is that the information from the prepared statement response is required to robustly serialize user defined types, as UDTs require their fields to be serialized in the same order as they are defined in the database schema. The IntoUserType macro which implements Rust struct -> UDT serialization just expects that the order of the Rust struct fields matches the schema, but ensuring this can be very cumbersome for the users.

          +

          In version 0.11, a new set of traits is introduced and the old ones are deprecated. The new traits receive more information during serialization such as names of the column/bind markers and their types, which allows to fix the issues mentioned in the previous section.

          +
          +
          +

          Old vs. new

          +

          Both the old and the new APIs are based on three core traits:

          +
            +
          • Value - called SerializeCql in the new API. A type that can serialize itself to a single CQL value. For example, i32 serializes itself into a representation that is compatible with the CQL int type.

          • +
          • ValueList - called SerializeRow in the new API. A type that can serialize itself as a list of values for a CQL statement. For example, a (i32, &str) produces a list of two values which can be used in a query with two bind markers, e.g. SELECT * FROM table WHERE pk = ? AND ck = ?. Optionally, values in the produced list may be associated with names which is useful when using it with a query with named bind markers, e.g. SELECT * FROM table WHERE pk = :pk AND ck = :ck.

          • +
          • LegacyBatchValues, previously named BatchValues - in new API replaced with new trait called (again) BatchValues. Represents a source of data for a batch request. It is essentially equivalent to a list of ValueList, one for each statement in the batch. For example, ((1, 2), (3, 4, 5)) can be used for a batch with two statements, the first one having two bind markers and the second one having three.

          • +
          +

          All methods which take one of the old traits were changed to take the new trait - notably, this includes Session::query, (Caching)Session::execute, (Caching)Session::batch.

          +

          The driver comes a set of impls of those traits which allow to represent any CQL type (for example, see Data Types page for a list of for which Value and SerializeCql is implemented). If the driver implements an old trait for some type, then it also provides implements the new trait for the same type.

          +
          +
          +

          Migration scenarios

          +
          +

          Different default behavior in SerializeRow/SerializeCql macros

          +

          By default, the SerializeRow and SerializeCql will match the fields in the Rust struct by name to bind marker names (in case of SerializeRow) or UDT field names (in case of SerializeCql). This is different from the old ValueList and IntoUserType macros which did not look at the field names at all and would expect the user to order the fields correctly. While the new behavior is much more ergonomic, you might have reasons not to use it.

          +
          +

          NOTE: The deserialization macro counterparts FromRow and FromUserType have the same limitation as the old serialization macros - they require struct fields to be properly ordered. While a similar rework is planned for the deserialization traits in a future release, for the time being it might not be worth keeping the column names in sync with the database.

          +
          +

          In order to bring the old behavior to the new macros (the only difference being type checking which cannot be disabled right now) you can configure it using attributes, as shown in the snippet below:

          +
          use scylla::SerializeCql;
          +
          +// The exact same attributes apply to the `SerializeRow` macro and their
          +// effect is completely analogous.
          +#[derive(SerializeCql)]
          +#[scylla(flavor = "enforce_order", skip_name_checks)]
          +struct Person {
          +    name: String,
          +    surname: String,
          +    age: i16,
          +}
          +
          +
          +

          Refer to the API reference page for the SerializeRow and SerializeCql macros in the scylla crate to learn more about the supported attributes and their meaning.

          +
          +
          +

          Preparing is mandatory with a non-empty list of values

          +
          +

          NOTE: The considerations in this section only concerns users of the Session API, CachingSession is not affected as it already does preparation before execute and caches the result.

          +
          +

          As explained in the Background section, the driver uses data returned from the database after preparing a statement in order to implement type checking. As the new API makes type checking mandatory, the driver must prepare the statement so that the data for the bind markers can be type checked. It is done in case of the existing methods which used to send unprepared statements: Session::query and Session::batch.

          +
          +

          NOTE: The driver will skip preparation if it detects that the list of values for the statement is empty, as there is nothing to be type checked.

          +
          +

          If you send simple statements along with non-empty lists of values, the slowdown will be as follows:

          +
            +
          • For Session::query, the driver will prepare the statement before sending it, incurring an additional round-trip.

          • +
          • For Session::batch, the driver will send a prepare request for each unique unprepared statement with a non-empty list of values. This is done serially!

          • +
          +

          In both cases, if the additional roundtrips are unacceptable, you should prepare the statements beforehand and reuse them - which aligns with our general recommendation against use of simple statements in performance sensitive scenarios.

          +
          +
          +

          Migrating from old to new traits gradually

          +

          In some cases, migration will be as easy as changing occurrences of IntoUserType to SerializeCql and ValueList to SerializeRow and adding some atributes for procedural macros. However, if you have a large enough codebase or some custom, complicated implementations of the old traits then you might not want to migrate everything at once. To support gradual migration, the old traits were not removed but rather deprecated, and we introduced some additional utilities.

          +
          +

          Converting an object implementing an old trait to a new trait

          +

          We provide a number of newtype wrappers:

          +
            +
          • ValueAdapter - implements SerializeCql if the type wrapped over implements Value,

          • +
          • ValueListAdapter - implements SerializeRow if the type wrapped over implements ValueList,

          • +
          • LegacyBatchValuesAdapter - implements BatchValues if the type wrapped over implements LegacyBatchValues.

          • +
          +

          Note that these wrappers are not zero cost and incur some overhead: in case of ValueAdapter and ValueListAdapter, the data is first written into a newly allocated buffer and then rewritten to the final buffer. In case of LegacyBatchValuesAdapter there shouldn’t be any additional allocations unless the implementation has an efficient, non-default Self::LegacyBatchValuesIterator::write_next_to_request implementation (which is not the case for the built-in impls).

          +

          Naturally, the implementations provided by the wrappers are not type safe as they directly use methods from the old traits.

          +

          Conversion in the other direction is not possible.

          +
          +
          +

          Custom implementations of old traits

          +

          It is possible to directly generate an impl of SerializeRow and SerializeCql on a type which implements, respectively, ValueList or Value, without using the wrappers from the previous section. The following macros are provided:

          +
            +
          • impl_serialize_cql_via_value - implements SerializeCql if the type wrapped over implements Value,

          • +
          • impl_serialize_row_via_value_list - implements SerializeRow if the type wrapped over implements ValueList,

          • +
          +

          The implementations are practically as those generated by the wrappers described in the previous section.

          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/migration-guides/migration-guides.html b/v0.12.0/migration-guides/migration-guides.html new file mode 100644 index 0000000000..a0d14052d4 --- /dev/null +++ b/v0.12.0/migration-guides/migration-guides.html @@ -0,0 +1,619 @@ + + + + + + + + + + + + + Migration guides | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Migration guides

          + +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/objects.inv b/v0.12.0/objects.inv new file mode 100644 index 0000000000..5d605ef479 Binary files /dev/null and b/v0.12.0/objects.inv differ diff --git a/v0.12.0/queries/batch.html b/v0.12.0/queries/batch.html new file mode 100644 index 0000000000..7ad9009c5d --- /dev/null +++ b/v0.12.0/queries/batch.html @@ -0,0 +1,756 @@ + + + + + + + + + + + + + Batch statement | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Batch statement

          +

          A batch statement allows to execute many data-modifying statements at once.
          +These statements can be simple or prepared.
          +Only INSERT, UPDATE and DELETE statements are allowed.

          +
          use scylla::batch::Batch;
          +use scylla::query::Query;
          +use scylla::prepared_statement::PreparedStatement;
          +
          +// Create a batch statement
          +let mut batch: Batch = Default::default();
          +
          +// Add a simple statement to the batch using its text
          +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(1, 2)");
          +
          +// Add a simple statement created manually to the batch
          +let simple: Query = Query::new("INSERT INTO ks.tab (a, b) VALUES(3, 4)");
          +batch.append_statement(simple);
          +
          +// Add a prepared statement to the batch
          +let prepared: PreparedStatement = session
          +    .prepare("INSERT INTO ks.tab (a, b) VALUES(?, 6)")
          +    .await?;
          +batch.append_statement(prepared);
          +
          +// Specify bound values to use with each statement
          +let batch_values = ((),
          +                    (),
          +                    (5_i32,));
          +
          +// Run the batch
          +session.batch(&batch, batch_values).await?;
          +
          +
          +
          +

          Warning
          +Using simple statements with bind markers in batches is strongly discouraged. +For each simple statement with a non-empty list of values in the batch, +the driver will send a prepare request, and it will be done sequentially. +Results of preparation are not cached between Session::batch calls. +Consider preparing the statements before putting them into the batch.

          +
          +
          +

          Preparing a batch

          +

          Instead of preparing each statement individually, it’s possible to prepare a whole batch at once:

          +
          use scylla::batch::Batch;
          +
          +// Create a batch statement with unprepared statements
          +let mut batch: Batch = Default::default();
          +batch.append_statement("INSERT INTO ks.simple_unprepared1 VALUES(?, ?)");
          +batch.append_statement("INSERT INTO ks.simple_unprepared2 VALUES(?, ?)");
          +
          +// Prepare all statements in the batch at once
          +let prepared_batch: Batch = session.prepare_batch(&batch).await?;
          +
          +// Specify bound values to use with each statement
          +let batch_values = ((1_i32, 2_i32),
          +                    (3_i32, 4_i32));
          +
          +// Run the prepared batch
          +session.batch(&prepared_batch, batch_values).await?;
          +
          +
          +
          +
          +

          Batch options

          +

          You can set various options by operating on the Batch object.
          +For example to change consistency:

          +
          use scylla::batch::Batch;
          +use scylla::statement::Consistency;
          +
          +// Create a batch
          +let mut batch: Batch = Default::default();
          +batch.append_statement("INSERT INTO ks.tab(a) VALUES(16)");
          +
          +// Set batch consistency to One
          +batch.set_consistency(Consistency::One);
          +
          +// Run the batch
          +session.batch(&batch, ((), )).await?;
          +
          +
          +

          See Batch API documentation +for more options

          +
          +
          +

          Batch values

          +

          Batch takes a tuple of values specified just like in simple or prepared queries.

          +

          Length of batch values must be equal to the number of statements in a batch.
          +Each statement must have its values specified, even if they are empty.

          +

          Values passed to Session::batch must implement the trait BatchValues.
          +By default this includes tuples () and slices &[] of tuples and slices which implement ValueList.

          +

          Example:

          +
          use scylla::batch::Batch;
          +
          +let mut batch: Batch = Default::default();
          +
          +// A statement with two bound values
          +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(?, ?)");
          +
          +// A statement with one bound value
          +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(3, ?)");
          +
          +// A statement with no bound values
          +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(5, 6)");
          +
          +// Batch values is a tuple of 3 tuples containing values for each statement
          +let batch_values = ((1_i32, 2_i32), // Tuple with two values for the first statement
          +                    (4_i32,),       // Tuple with one value for the second statement
          +                    ());            // Empty tuple/unit for the third statement
          +
          +// Run the batch
          +// Note that the driver will prepare the first two statements, due to them
          +// not being prepared and having a non-empty list of values.
          +session.batch(&batch, batch_values).await?;
          +
          +
          +

          For more information about sending values in a statement see Query values

          +
          +
          +

          Performance

          +

          Batch statements do not use token/shard aware load balancing, batches are sent to a random node.

          +

          Use prepared queries for best performance

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/lwt.html b/v0.12.0/queries/lwt.html new file mode 100644 index 0000000000..9253519e03 --- /dev/null +++ b/v0.12.0/queries/lwt.html @@ -0,0 +1,652 @@ + + + + + + + + + + + + + Lightweight transaction (LWT) query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Lightweight transaction (LWT) query

          +

          A lightweight transaction query can be expressed just like any other query, via Session, with the notable difference of having an additional consistency level parameter - the serial_consistency_level.

          +
          +

          Format of the query

          +

          A lightweight transaction query is not a separate type - it can be expressed just like any other queries: via SimpleQuery, PreparedStatement, batches, and so on. The difference lays in the query string itself - when it contains a condition (e.g. IF NOT EXISTS), it becomes a lightweight transaction. It’s important to remember that CQL specification requires a separate, additional consistency level to be defined for LWT queries - serial_consistency_level. The serial consistency level can only be set to two values: SerialConsistency::Serial or SerialConsistency::LocalSerial. The “local” variant makes the transaction consistent only within the same datacenter. For convenience, Scylla Rust Driver sets the default consistency level to LocalSerial, as it’s more commonly used. For cross-datacenter consistency, please remember to always override the default with SerialConsistency::Serial.

          +
          use scylla::query::Query;
          +use scylla::statement::{Consistency, SerialConsistency};
          +
          +// Create a Query manually to change the Consistency to ONE
          +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?) IF NOT EXISTS".to_string());
          +my_query.set_consistency(Consistency::One);
          +// Use cross-datacenter serial consistency
          +my_query.set_serial_consistency(Some(SerialConsistency::Serial));
          +
          +// Insert a value into the table
          +let to_insert: i32 = 12345;
          +session.query(my_query, (to_insert,)).await?;
          +
          +
          +

          The rest of the API remains identical for LWT and non-LWT queries.

          +

          See Query API documentation for more options

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/paged.html b/v0.12.0/queries/paged.html new file mode 100644 index 0000000000..a615547b06 --- /dev/null +++ b/v0.12.0/queries/paged.html @@ -0,0 +1,750 @@ + + + + + + + + + + + + + Paged query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Paged query

          +

          Sometimes query results might not fit in a single page. Paged queries +allow to receive the whole result page by page.

          +

          Session::query_iter and Session::execute_iter take a simple query or a prepared query +and return an async iterator over result Rows.

          +
          +

          Warning
          +In case of unprepared variant (Session::query_iter) if the values are not empty +driver will first fully prepare a query (which means issuing additional request to each +node in a cluster). This will have a performance penalty - how big it is depends on +the size of your cluster (more nodes - more requests) and the size of returned +result (more returned pages - more amortized penalty). In any case, it is preferable to +use Session::execute_iter.

          +
          +
          +

          Examples

          +

          Use query_iter to perform a simple query with paging:

          +
          use scylla::IntoTypedRows;
          +use futures::stream::StreamExt;
          +
          +let mut rows_stream = session
          +    .query_iter("SELECT a, b FROM ks.t", &[])
          +    .await?
          +    .into_typed::<(i32, i32)>();
          +
          +while let Some(next_row_res) = rows_stream.next().await {
          +    let (a, b): (i32, i32) = next_row_res?;
          +    println!("a, b: {}, {}", a, b);
          +}
          +
          +
          +

          Use execute_iter to perform a prepared query with paging:

          +
          use scylla::IntoTypedRows;
          +use scylla::prepared_statement::PreparedStatement;
          +use futures::stream::StreamExt;
          +
          +let prepared: PreparedStatement = session
          +    .prepare("SELECT a, b FROM ks.t")
          +    .await?;
          +
          +let mut rows_stream = session
          +    .execute_iter(prepared, &[])
          +    .await?
          +    .into_typed::<(i32, i32)>();
          +
          +while let Some(next_row_res) = rows_stream.next().await {
          +    let (a, b): (i32, i32) = next_row_res?;
          +    println!("a, b: {}, {}", a, b);
          +}
          +
          +
          +

          Query values can be passed to query_iter and execute_iter just like in a simple query

          +
          +
          +

          Configuring page size

          +

          It’s possible to configure the size of a single page.

          +

          On a Query:

          +
          use scylla::query::Query;
          +
          +let mut query: Query = Query::new("SELECT a, b FROM ks.t");
          +query.set_page_size(16);
          +
          +let _ = session.query_iter(query, &[]).await?; // ...
          +
          +
          +

          On a PreparedStatement:

          +
          use scylla::prepared_statement::PreparedStatement;
          +
          +let mut prepared: PreparedStatement = session
          +    .prepare("SELECT a, b FROM ks.t")
          +    .await?;
          +
          +prepared.set_page_size(16);
          +
          +let _ = session.execute_iter(prepared, &[]).await?; // ...
          +
          +
          +
          +
          +

          Passing the paging state manually

          +

          It’s possible to fetch a single page from the table, extract the paging state +from the result and manually pass it to the next query. That way, the next +query will start fetching the results from where the previous one left off.

          +

          On a Query:

          +
          use scylla::query::Query;
          +
          +let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6);
          +let res1 = session.query(paged_query.clone(), &[]).await?;
          +let res2 = session
          +    .query_paged(paged_query.clone(), &[], res1.paging_state)
          +    .await?;
          +
          +
          +
          +

          Warning
          +If the values are not empty, driver first needs to send a PREPARE request +in order to fetch information required to serialize values. This will affect +performance because 2 round trips will be required instead of 1.

          +
          +

          On a PreparedStatement:

          +
          use scylla::query::Query;
          +
          +let paged_prepared = session
          +    .prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7))
          +    .await?;
          +let res1 = session.execute(&paged_prepared, &[]).await?;
          +let res2 = session
          +    .execute_paged(&paged_prepared, &[], res1.paging_state)
          +    .await?;
          +
          +
          +
          +
          +

          Performance

          +

          Performance is the same as in non-paged variants.
          +For the best performance use prepared queries.

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/prepared.html b/v0.12.0/queries/prepared.html new file mode 100644 index 0000000000..2f8871a3b1 --- /dev/null +++ b/v0.12.0/queries/prepared.html @@ -0,0 +1,738 @@ + + + + + + + + + + + + + Prepared query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Prepared query

          +

          Prepared queries provide much better performance than simple queries, +but they need to be prepared before use.

          +
          use scylla::prepared_statement::PreparedStatement;
          +
          +// Prepare the query for later execution
          +let prepared: PreparedStatement = session
          +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
          +    .await?;
          +
          +// Run the prepared query with some values, just like a simple query
          +let to_insert: i32 = 12345;
          +session.execute(&prepared, (to_insert,)).await?;
          +
          +
          +
          +

          Warning
          +For token/shard aware load balancing to work properly, all partition key values +must be sent as bound values (see performance section)

          +
          +
          +

          Warning
          +Don’t use execute to receive large amounts of data.
          +By default the query is unpaged and might cause heavy load on the cluster. +In such cases set a page size and use a paged query instead.

          +

          When page size is set, execute will return only the first page of results.

          +
          +
          +

          Session::prepare

          +

          Session::prepare takes query text and prepares the query on all nodes and shards. +If at least one succeeds returns success.

          +
          +
          +

          Session::execute

          +

          Session::execute takes a prepared query and bound values and runs the query. +Passing values and the result is the same as in simple query.

          +
          +
          +

          Query options

          +

          To specify custom options, set them on the PreparedStatement before execution. +For example to change the consistency:

          +
          use scylla::prepared_statement::PreparedStatement;
          +use scylla::statement::Consistency;
          +
          +// Prepare the query for later execution
          +let mut prepared: PreparedStatement = session
          +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
          +    .await?;
          +
          +// Set prepared query consistency to One
          +// This is the consistency with which this query will be executed
          +prepared.set_consistency(Consistency::One);
          +
          +// Run the prepared query with some values, just like a simple query
          +let to_insert: i32 = 12345;
          +session.execute(&prepared, (to_insert,)).await?;
          +
          +
          +

          See PreparedStatement API documentation +for more options.

          +
          +

          Note +Prepared statements can be created from Query structs and will inherit from +the custom options that the Query was created with. +This is especially useful when using CachingSession::execute for example.

          +
          +
          +
          +

          Performance

          +

          Prepared queries have good performance, much better than simple queries. +By default they use shard/token aware load balancing.

          +
          +

          Always pass partition key values as bound values. +Otherwise the driver can’t hash them to compute partition key +and they will be sent to the wrong node, which worsens performance.

          +
          +

          Let’s say we have a table like this:

          +
          TABLE ks.prepare_table (
          +    a int,
          +    b int,
          +    c int,
          +    PRIMARY KEY (a, b)
          +)
          +
          +
          +
          use scylla::prepared_statement::PreparedStatement;
          +
          +// WRONG - partition key value is passed in query string
          +// Load balancing will compute the wrong partition key
          +let wrong_prepared: PreparedStatement = session
          +    .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(12345, ?, 16)")
          +    .await?;
          +
          +session.execute(&wrong_prepared, (54321,)).await?;
          +
          +// GOOD - partition key values are sent as bound values
          +// Other values can be sent any way you like, it doesn't matter
          +let good_prepared: PreparedStatement = session
          +    .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(?, ?, 16)")
          +    .await?;
          +
          +session.execute(&good_prepared, (12345, 54321)).await?;
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/queries.html b/v0.12.0/queries/queries.html new file mode 100644 index 0000000000..8c5927ff40 --- /dev/null +++ b/v0.12.0/queries/queries.html @@ -0,0 +1,648 @@ + + + + + + + + + + + + + Making queries | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Making queries

          +

          This driver supports all query types available in Scylla:

          +
            +
          • Simple queries

            +
              +
            • Easy to use

            • +
            • Poor performance

            • +
            • Primitive load balancing

            • +
            +
          • +
          • Prepared queries

            +
              +
            • Need to be prepared before use

            • +
            • Fast

            • +
            • Properly load balanced

            • +
            +
          • +
          • Batch statements

            +
              +
            • Run multiple queries at once

            • +
            • Can be prepared for better performance and load balancing

            • +
            +
          • +
          • Paged queries

            +
              +
            • Allows to read result in multiple pages when it doesn’t fit in a single response

            • +
            • Can be prepared for better performance and load balancing

            • +
            +
          • +
          +

          Additionally there is special functionality to enable USE KEYSPACE queries: +USE keyspace

          +

          Queries are fully asynchronous - you can run as many of them in parallel as you wish.

          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/result.html b/v0.12.0/queries/result.html new file mode 100644 index 0000000000..8102282851 --- /dev/null +++ b/v0.12.0/queries/result.html @@ -0,0 +1,758 @@ + + + + + + + + + + + + + Query result | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Query result

          +

          Session::query and Session::execute return a QueryResult with rows represented as Option<Vec<Row>>.

          +
          +

          Basic representation

          +

          Row is a basic representation of a received row. It can be used by itself, but it’s a bit awkward to use:

          +
          if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
          +    for row in rows {
          +        let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap();
          +    }
          +}
          +
          +
          +
          +
          +

          Parsing using into_typed

          +

          The driver provides a way to parse a row as a tuple of Rust types:

          +
          use scylla::IntoTypedRows;
          +
          +// Parse row as a single column containing an int value
          +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
          +    for row in rows {
          +        let (int_value,): (i32,) = row.into_typed::<(i32,)>()?;
          +    }
          +}
          +
          +// rows.into_typed() converts a Vec of Rows to an iterator of parsing results
          +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
          +    for row in rows.into_typed::<(i32,)>() {
          +        let (int_value,): (i32,) = row?;
          +    }
          +}
          +
          +// Parse row as two columns containing an int and text columns
          +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
          +    for row in rows.into_typed::<(i32, String)>() {
          +        let (int_value, text_value): (i32, String) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Parsing using convenience methods

          +

          QueryResult provides convenience methods for parsing rows. +Here are a few of them:

          +
            +
          • rows_typed::<RowT>() - returns the rows parsed as the given type

          • +
          • maybe_first_row_typed::<RowT> - returns Option<RowT> containing first row from the result

          • +
          • first_row_typed::<RowT> - same as maybe_first_row, but fails without the first row

          • +
          • single_row_typed::<RowT> - same as first_row, but fails when there is more than one row

          • +
          • result_not_rows() - ensures that query response was not rows, helps avoid bugs

          • +
          +
          // Parse row as a single column containing an int value
          +let rows = session
          +    .query("SELECT a from ks.tab", &[])
          +    .await?
          +    .rows_typed::<(i32,)>()?; // Same as .rows()?.into_typed()
          +for row in rows {
          +    let (int_value,): (i32,) = row?;
          +}
          +
          +// maybe_first_row_typed gets the first row and parses it as the given type
          +let first_int_val: Option<(i32,)> = session
          +    .query("SELECT a from ks.tab", &[])
          +    .await?
          +    .maybe_first_row_typed::<(i32,)>()?;
          +
          +// no_rows fails when the response is rows
          +session.query("INSERT INTO ks.tab (a) VALUES (0)", &[]).await?.result_not_rows()?;
          +
          +
          +

          For more see QueryResult

          +
          +

          NULL values

          +

          NULL values will return an error when parsed as a Rust type. +To properly handle NULL values parse column as an Option<>:

          +
          use scylla::IntoTypedRows;
          +
          +// Parse row as two columns containing an int and text which might be null
          +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
          +    for row in rows.into_typed::<(i32, Option<String>)>() {
          +        let (int_value, str_or_null): (i32, Option<String>) = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Parsing row as a custom struct

          +

          It is possible to receive row as a struct with fields matching the columns.
          +The struct must:

          +
            +
          • have the same number of fields as the number of queried columns

          • +
          • have field types matching the columns being received

          • +
          • derive FromRow

          • +
          +

          Field names don’t need to match column names.

          +
          use scylla::IntoTypedRows;
          +use scylla::macros::FromRow;
          +use scylla::frame::response::cql_to_rust::FromRow;
          +
          +#[derive(FromRow)]
          +struct MyRow {
          +    age: i32,
          +    name: Option<String>
          +}
          +
          +// Parse row as two columns containing an int and text which might be null
          +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
          +    for row in rows.into_typed::<MyRow>() {
          +        let my_row: MyRow = row?;
          +    }
          +}
          +
          +
          +
          +
          +

          Other data types

          +

          For parsing other data types see Data Types

          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/schema-agreement.html b/v0.12.0/queries/schema-agreement.html new file mode 100644 index 0000000000..599a612653 --- /dev/null +++ b/v0.12.0/queries/schema-agreement.html @@ -0,0 +1,681 @@ + + + + + + + + + + + + + Schema agreement | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Schema agreement

          +

          Sometimes after performing queries some nodes have not been updated, so we need a mechanism that checks if every node have agreed on schema version.

          +
          +

          Automated awaiting schema agreement

          +

          The driver automatically awaits schema agreement after a schema-altering query is executed. +Waiting for schema agreement more than necessary is never a bug, but might slow down applications which do a lot of schema changes (e.g. a migration). +For instance, in case where somebody wishes to create a keyspace and then a lot of tables in it, it makes sense only to wait after creating a keyspace +and after creating all the tables rather than after every query. Therefore, the said behaviour can be disabled:

          +
          let session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .auto_await_schema_agreement(false)
          +    .build()
          +    .await?;
          +
          +
          +
          +
          +

          Manually awaiting schema agreement

          +

          Session::await_schema_agreement returns a Future that can be awaited as long as schema is not in an agreement. +However, it won’t wait forever; SessionConfig defines a timeout that limits the time of waiting. If the timeout elapses, +the return value is Err(QueryError::RequestTimeout), otherwise it is Ok(schema_version).

          +
          session.await_schema_agreement().await?;
          +
          +
          +
          +
          +

          Interval of checking for schema agreement

          +

          If the schema is not agreed upon, the driver sleeps for a duration before checking it again. The default value is 200 milliseconds, +but it can be changed with SessionBuilder::schema_agreement_interval.

          +
          SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .schema_agreement_interval(Duration::from_secs(1))
          +    .build()
          +    .await?;
          +
          +
          +
          +
          +

          Checking if schema is in agreement now

          +

          If you want to check if schema is in agreement now, without retrying after failure, you can use Session::check_schema_agreement function.

          +
          if session.check_schema_agreement().await?.is_some() {
          +    println!("SCHEMA AGREED");
          +} else {
          +    println!("SCHEMA IS NOT IN AGREEMENT");
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/simple.html b/v0.12.0/queries/simple.html new file mode 100644 index 0000000000..8108405661 --- /dev/null +++ b/v0.12.0/queries/simple.html @@ -0,0 +1,720 @@ + + + + + + + + + + + + + Simple query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Simple query

          +

          Simple query takes query text and values and simply executes them on a Session:

          +
          // Insert a value into the table
          +let to_insert: i32 = 12345;
          +session
          +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
          +    .await?;
          +
          +
          +
          +

          Warning
          +Don’t use simple query to receive large amounts of data.
          +By default the query is unpaged and might cause heavy load on the cluster.
          +In such cases set a page size and use paged query instead.\

          +

          When page size is set, query will return only the first page of results.

          +
          +
          +

          Warning
          +If the values are not empty, driver first needs to send a PREPARE request +in order to fetch information required to serialize values. This will affect +performance because 2 round trips will be required instead of 1.

          +
          +
          +

          First argument - the query

          +

          As the first argument Session::query takes anything implementing Into<Query>.
          +You can create a query manually to set custom options. For example to change query consistency:

          +
          use scylla::query::Query;
          +use scylla::statement::Consistency;
          +
          +// Create a Query manually to change the Consistency to ONE
          +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
          +my_query.set_consistency(Consistency::One);
          +
          +// Insert a value into the table
          +let to_insert: i32 = 12345;
          +session.query(my_query, (to_insert,)).await?;
          +
          +
          +

          See Query API documentation for more options

          +
          +
          +

          Second argument - the values

          +

          Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.
          +Each ? in query text will be filled with the matching value.

          +

          The easiest way is to pass values using a tuple:

          +
          // Sending an integer and a string using a tuple
          +session
          +    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, 'text2')", (2_i32, "Some text"))
          +    .await?;
          +
          +
          +

          Here the first ? will be filled with 2 and the second with "Some text".

          +
          +

          Never pass values by adding strings, this could lead to SQL Injection

          +
          +

          See Query values for more information about sending values in queries

          +
          +
          +

          Query result

          +

          Session::query returns QueryResult with rows represented as Option<Vec<Row>>.
          +Each row can be parsed as a tuple of rust types using into_typed:

          +
          use scylla::IntoTypedRows;
          +
          +// Query rows from the table and print them
          +if let Some(rows) = session.query("SELECT a FROM ks.tab", &[]).await?.rows {
          +    // Parse each row as a tuple containing single i32
          +    for row in rows.into_typed::<(i32,)>() {
          +        let read_row: (i32,) = row?;
          +        println!("Read a value from row: {}", read_row.0);
          +    }
          +}
          +
          +
          +
          +

          In cases where page size is set, simple query returns only a single page of results.
          +To receive all pages use a paged query instead.\

          +
          +

          See Query result for more information about handling query results

          +
          +
          +

          Performance

          +

          Simple queries should not be used in places where performance matters.
          +If performance matters use a Prepared query instead.

          +

          With simple query the database has to parse query text each time it’s executed, which worsens performance.\

          +

          Additionally token and shard aware load balancing does not work with simple queries. They are sent to random nodes.

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/timeouts.html b/v0.12.0/queries/timeouts.html new file mode 100644 index 0000000000..99fcb5ce12 --- /dev/null +++ b/v0.12.0/queries/timeouts.html @@ -0,0 +1,667 @@ + + + + + + + + + + + + + Query timeouts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Query timeouts

          +

          Query execution time can be limited by setting a request timeout. If a query does not complete +in the given time, then QueryError::RequestTimeout is returned by the driver immediately, +so that application logic can continue operating, but the query may still be in progress on the server.

          +

          As a side note, if one wishes custom server-side timeouts (i.e. actual interruption of query processing), +one can use aUSING TIMEOUT <duration> directive supported in ScyllaDB +(but not in Cassandra).

          +

          Timeout can be set globally (per session) or locally (for given statement). +The default per-session timeout is currently 30s. +It is possible to turn off timeouts completely by providing None as timeout when building Session. +However, setting per-statement timeout to None results in falling back to per-session timeout.

          +
          use scylla::{Session, SessionBuilder, query::Query};
          +use scylla::transport::ExecutionProfile;
          +use std::time::Duration;
          +
          +let uri = std::env::var("SCYLLA_URI")
          +    .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
          +
          +let no_timeout_profile_handle = ExecutionProfile::builder()
          +    .request_timeout(None) // no timeout
          +    .build()
          +    .into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node(uri)
          +    .default_execution_profile_handle(no_timeout_profile_handle) // no per-session timeout
          +    .build()
          +    .await?;
          +
          +// This query, having no timeout, could block indefinitely if a queried node hangs.
          +session
          +    .query("TRUNCATE keyspace.table", ())
          +    .await?;
          +
          +let three_sec_timeout_profile_handle = ExecutionProfile::builder()
          +    .request_timeout(Some(Duration::from_secs(3))) // no timeout
          +    .build()
          +    .into_handle();
          +
          +// The below query will last for no more than 3 seconds, yielding a RequestTimeout error
          +// if no response arrives until then.
          +let mut query: Query = "TRUNCATE keyspace.table".into();
          +query.set_execution_profile_handle(Some(three_sec_timeout_profile_handle));
          +session
          +    .query(query, ())
          +    .await?;
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/usekeyspace.html b/v0.12.0/queries/usekeyspace.html new file mode 100644 index 0000000000..589ff79e87 --- /dev/null +++ b/v0.12.0/queries/usekeyspace.html @@ -0,0 +1,701 @@ + + + + + + + + + + + + + USE keyspace | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          USE keyspace

          +

          Using a keyspace allows to omit keyspace name in queries.

          +

          For example in cqlsh one could write:

          +
          cqlsh> SELECT * FROM my_keyspace.table;
          +
          + a     | b     |
          +-------+-------+
          + 12345 | 54321 |
          +
          +(1 rows)
          +cqlsh> USE my_keyspace;
          +cqlsh:my_keyspace> SELECT * FROM table;
          +
          + a     | b     |
          +-------+-------+
          + 12345 | 54321 |
          +
          +(1 rows)
          +
          +
          +

          Tables from other keyspaces can still easily be accessed by using their keyspace names.

          +
          cqlsh:my_keyspace> SELECT * FROM other_keyspace.other_table;
          +
          +
          +

          In the driver this can be achieved using Session::use_keyspace:

          +
          session
          +    .query("INSERT INTO my_keyspace.tab (a) VALUES ('test1')", &[])
          +    .await?;
          +
          +session.use_keyspace("my_keyspace", false).await?;
          +
          +// Now we can omit keyspace name in the query
          +session
          +    .query("INSERT INTO tab (a) VALUES ('test2')", &[])
          +    .await?;
          +
          +
          +

          The first argument is the keyspace name.
          +The second argument states whether this name is case sensitive.

          +

          It is also possible to send raw use keyspace query using Session::query instead of Session::use_keyspace such as:

          +
          session.query("USE my_keyspace", &[]).await?;
          +
          +
          +

          This method has a slightly worse latency than Session::use_keyspace - there are two roundtrips needed instead of one. +Therefore, Session::use_keyspace is the preferred method for setting keyspaces.

          +
          +

          Multiple use queries at once

          +

          Don’t run multiple use_keyspace queries at once. +This could end up with half of connections using one keyspace and the other half using the other.

          +
          +
          +

          Case sensitivity

          +

          In CQL a keyspace name can be case insensitive (without ") or case sensitive (with ").
          +If the second argument to use_keyspace is set to true this keyspace name will be wrapped in ".
          +It is best to avoid the problem altogether and just not create two keyspaces with the same name but different cases.

          +

          Let’s see what happens when there are two keyspaces with the same name but different cases: my_keyspace and MY_KEYSPACE:

          +
          // lowercase name without case sensitivity will use my_keyspace
          +session.use_keyspace("my_keyspace", false).await?;
          +
          +// lowercase name with case sensitivity will use my_keyspace
          +session.use_keyspace("my_keyspace", true).await?;
          +
          +// uppercase name without case sensitivity will use my_keyspace
          +session.use_keyspace("MY_KEYSPACE", false).await?;
          +
          +// uppercase name with case sensitivity will use MY_KEYSPACE
          +session.use_keyspace("MY_KEYSPACE", true).await?;
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/queries/values.html b/v0.12.0/queries/values.html new file mode 100644 index 0000000000..6d0e62857a --- /dev/null +++ b/v0.12.0/queries/values.html @@ -0,0 +1,757 @@ + + + + + + + + + + + + + Query values | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Query values

          +

          Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.
          +Each ? in query text will be filled with the matching value.

          +
          +

          Never pass values by adding strings, this could lead to SQL Injection

          +
          +

          Each list of values to send in a query must implement the trait SerializeRow.
          +By default this can be a slice &[], a tuple () (max 16 elements) of values to send, +or a custom struct which derives from SerializeRow.

          +

          A few examples:

          +
          // Empty slice means that there are no values to send
          +session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?;
          +
          +// Empty tuple/unit also means that there are no values to send
          +session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?;
          +
          +// Sending three integers using a slice:
          +session
          +    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref())
          +    .await?;
          +
          +// Sending an integer and a string using a tuple
          +session
          +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text"))
          +    .await?;
          +
          +// Sending an integer and a string using a named struct.
          +// Names of fields must match names of columns in request,
          +// but having them in the same order is not required.
          +// If the fields are in the same order, you can use attribute:
          +// `#[scylla(flavor = "enforce_order")]`
          +// in order to skip sorting the fields and just check if they
          +// are in the same order. See documentation of this macro
          +// for more information.
          +#[derive(SerializeRow)]
          +struct IntString {
          +    a: i32,
          +    b: String,
          +}
          +
          +let int_string = IntString {
          +    a: 42_i32,
          +    b: "hello".to_owned(),
          +};
          +
          +session
          +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string)
          +    .await?;
          +
          +// You can use named bind markers in query if you want
          +// your names in struct to be different than column names.
          +#[derive(SerializeRow)]
          +struct IntStringCustom {
          +    first_value: i32,
          +    second_value: String,
          +}
          +
          +let int_string_custom = IntStringCustom {
          +    first_value: 42_i32,
          +    second_value: "hello".to_owned(),
          +};
          +
          +session
          +    .query("INSERT INTO ks.tab (a, b) VALUES(:first_value, :second_value)", int_string_custom)
          +    .await?;
          +
          +// Sending a single value as a tuple requires a trailing coma (Rust syntax):
          +session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?;
          +
          +// Each value can also be sent using a reference:
          +session
          +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text"))
          +    .await?;
          +
          +// A map of named values can also be provided:
          +let mut vals: HashMap<&str, CqlValue> = HashMap::new();
          +vals.insert("avalue", CqlValue::Text("hello".to_string()));
          +vals.insert("bvalue", CqlValue::Int(17));
          +session
          +    .query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals)
          +    .await?;
          +
          +
          +
          +

          NULL values

          +

          Null values can be sent using Option<> - sending a None will make the value NULL:

          +
          let null_i32: Option<i32> = None;
          +session
          +    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
          +    .await?;
          +
          +
          +
          +
          +

          Unset values

          +

          When performing an insert with values which might be NULL, it’s better to use Unset.
          +Database treats inserting NULL as a delete operation and will generate a tombstone. +Using Unset results in better performance:

          +
          use scylla::frame::value::{MaybeUnset, Unset};
          +
          +// Inserting a null results in suboptimal performance
          +let null_i32: Option<i32> = None;
          +session
          +    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
          +    .await?;
          +
          +// Using MaybeUnset enum is better
          +let unset_i32: MaybeUnset<i32> = MaybeUnset::Unset;
          +session
          +    .query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,))
          +    .await?;
          +
          +// If we are sure that a value should be unset we can simply use Unset
          +session
          +    .query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,))
          +    .await?;
          +
          +
          +

          See the issue for more information about Unset

          +
          +
          +

          Other data types

          +

          See Data Types for instructions on sending other data types

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/quickstart/create-project.html b/v0.12.0/quickstart/create-project.html new file mode 100644 index 0000000000..33bc20b70e --- /dev/null +++ b/v0.12.0/quickstart/create-project.html @@ -0,0 +1,649 @@ + + + + + + + + + + + + + Creating a project | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Creating a project

          +

          To create a new project run:

          +
          cargo new myproject
          +
          +
          +

          In Cargo.toml add useful dependencies:

          +
          [dependencies]
          +scylla = "0.12"
          +tokio = { version = "1.12", features = ["full"] }
          +futures = "0.3.6"
          +uuid = "1.0"
          +bigdecimal = "0.4"
          +num-bigint = "0.3"
          +tracing = "0.1.36"
          +tracing-subscriber = { version = "0.3.14", features = ["env-filter"] }
          +
          +
          +

          In main.rs put:

          +
          use scylla::Session;
          +
          +#[tokio::main]
          +async fn main() {
          +    println!("Hello scylla!");
          +}
          +
          +
          +

          Now running cargo run should print:

          +
          Hello scylla!
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/quickstart/example.html b/v0.12.0/quickstart/example.html new file mode 100644 index 0000000000..1ef0415d73 --- /dev/null +++ b/v0.12.0/quickstart/example.html @@ -0,0 +1,672 @@ + + + + + + + + + + + + + Connecting and running a simple query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Connecting and running a simple query

          +

          Now everything is ready to use the driver. +Here is a small example:

          +
          use scylla::{IntoTypedRows, Session, SessionBuilder};
          +use std::error::Error;
          +
          +#[tokio::main]
          +async fn main() -> Result<(), Box<dyn Error>> {
          +    // Create a new Session which connects to node at 127.0.0.1:9042
          +    // (or SCYLLA_URI if specified)
          +    let uri = std::env::var("SCYLLA_URI")
          +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
          +
          +    let session: Session = SessionBuilder::new()
          +        .known_node(uri)
          +        .build()
          +        .await?;
          +
          +    // Create an example keyspace and table
          +    session
          +        .query(
          +            "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \
          +            {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}",
          +            &[],
          +        )
          +        .await?;
          +
          +    session
          +        .query(
          +            "CREATE TABLE IF NOT EXISTS ks.extab (a int primary key)",
          +            &[],
          +        )
          +        .await?;
          +
          +    // Insert a value into the table
          +    let to_insert: i32 = 12345;
          +    session
          +        .query("INSERT INTO ks.extab (a) VALUES(?)", (to_insert,))
          +        .await?;
          +
          +    // Query rows from the table and print them
          +    if let Some(rows) = session.query("SELECT a FROM ks.extab", &[]).await?.rows {
          +        // Parse each row as a tuple containing single i32
          +        for row in rows.into_typed::<(i32,)>() {
          +            let read_row: (i32,) = row?;
          +            println!("Read a value from row: {}", read_row.0);
          +        }
          +    }
          +
          +    Ok(())
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/quickstart/quickstart.html b/v0.12.0/quickstart/quickstart.html new file mode 100644 index 0000000000..8a0052ba40 --- /dev/null +++ b/v0.12.0/quickstart/quickstart.html @@ -0,0 +1,623 @@ + + + + + + + + + + + + + Quick Start | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Quick Start

          +

          In this chapter we will set up a Rust project and run a few simple queries.

          +

          Topics Include:

          + +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/quickstart/scylla-docker.html b/v0.12.0/quickstart/scylla-docker.html new file mode 100644 index 0000000000..f55fe144e3 --- /dev/null +++ b/v0.12.0/quickstart/scylla-docker.html @@ -0,0 +1,652 @@ + + + + + + + + + + + + + Running Scylla using Docker | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Running Scylla using Docker

          +

          To make queries we will need a running Scylla instance. The easiest way is to use a Docker image.
          +Please install Docker if it’s not installed.

          +
          +

          Running scylla

          +

          To start Scylla run:

          +
          # on Linux sudo might be required
          +docker run --rm -it -p 9042:9042 scylladb/scylla --smp 2
          +
          +
          +

          Docker will download the image, then after minute or two there should be a message like:

          +
          Starting listening for CQL clients on 172.17.0.2:9042
          +
          +
          +

          This means that Scylla is ready to receive queries

          +

          To stop this instance press Ctrl + C

          +
          +
          +

          More information

          +

          More information about this image can be found on dockerhub

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/retry-policy/default.html b/v0.12.0/retry-policy/default.html new file mode 100644 index 0000000000..4cdc73ef05 --- /dev/null +++ b/v0.12.0/retry-policy/default.html @@ -0,0 +1,698 @@ + + + + + + + + + + + + + Default retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Default retry policy

          +

          This is the retry policy used by default. It retries when there is a high chance that it might help.
          +This policy is based on the one in DataStax Java Driver. +The behaviour is the same.

          +
          +

          Examples

          +

          To use in Session:

          +
          use scylla::{Session, SessionBuilder};
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::retry_policy::DefaultRetryPolicy;
          +
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .default_execution_profile_handle(handle)
          +    .build()
          +    .await?;
          +
          +
          +

          To use in a simple query:

          +
          use scylla::query::Query;
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::retry_policy::DefaultRetryPolicy;
          +
          +// Create a Query manually and set the retry policy
          +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
          +my_query.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new())));
          +
          +// You can also set retry policy in an execution profile
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +my_query.set_execution_profile_handle(Some(handle));
          +
          +// Run the query using this retry policy
          +let to_insert: i32 = 12345;
          +session.query(my_query, (to_insert,)).await?;
          +
          +
          +

          To use in a prepared query:

          +
          use scylla::prepared_statement::PreparedStatement;
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::retry_policy::DefaultRetryPolicy;
          +
          +// Create PreparedStatement manually and set the retry policy
          +let mut prepared: PreparedStatement = session
          +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
          +    .await?;
          +prepared.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new())));
          +
          +// You can also set retry policy in an execution profile
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +prepared.set_execution_profile_handle(Some(handle));
          +
          +// Run the query using this retry policy
          +let to_insert: i32 = 12345;
          +session.execute(&prepared, (to_insert,)).await?;
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/retry-policy/downgrading-consistency.html b/v0.12.0/retry-policy/downgrading-consistency.html new file mode 100644 index 0000000000..4ebf7192fa --- /dev/null +++ b/v0.12.0/retry-policy/downgrading-consistency.html @@ -0,0 +1,739 @@ + + + + + + + + + + + + + Downgrading consistency retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Downgrading consistency retry policy

          +

          A retry policy that sometimes retries with a lower consistency level than the one initially +requested. +BEWARE: this policy may retry queries using a lower consistency level than the one +initially requested. By doing so, it may break consistency guarantees. In other words, if you use +this retry policy, there are cases (documented below) where a read at Consistency::Quorum may +not see a preceding write at Consistency::Quorum. Do not use this policy unless you have +understood the cases where this can happen and are ok with that. It is also highly recommended to +always log the occurrences of such consistency breaks. +This policy implements the same retries than the DefaultRetryPolicy policy. But on top +of that, it also retries in the following cases:

          +
            +
          • On a read timeout: if the number of replicas that responded is greater than one, but lower +than is required by the requested consistency level, the operation is retried at a lower +consistency level.

          • +
          • On a write timeout: if the operation is a WriteType::UnloggedBatch and at least one +replica acknowledged the write, the operation is retried at a lower consistency level. +Furthermore, for other operations, if at least one replica acknowledged the write, the +timeout is ignored.

          • +
          • On an unavailable exception: if at least one replica is alive, the operation is retried at +a lower consistency level.

          • +
          +

          The lower consistency level to use for retries is determined by the following rules:

          +
            +
          • if more than 3 replicas responded, use Consistency::Three.

          • +
          • if 1, 2 or 3 replicas responded, use the corresponding level Consistency::One, Consistency::Two or +Consistency::Three.

          • +
          +

          Note that if the initial consistency level was Consistency::EachQuorum, Scylla returns the number +of live replicas in the datacenter that failed to reach consistency, not the overall +number in the cluster. Therefore if this number is 0, we still retry at Consistency::One, on the +assumption that a host may still be up in another datacenter. +The reasoning being this retry policy is the following one. If, based on the information the +Scylla coordinator node returns, retrying the operation with the initially requested +consistency has a chance to succeed, do it. Otherwise, if based on this information we know +the initially requested consistency level cannot be achieved currently, then:

          +
            +
          • For writes, ignore the exception (thus silently failing the consistency requirement) if we +know the write has been persisted on at least one replica.

          • +
          • For reads, try reading at a lower consistency level (thus silently failing the consistency +requirement). +In other words, this policy implements the idea that if the requested consistency level cannot be +achieved, the next best thing for writes is to make sure the data is persisted, and that reading +something is better than reading nothing, even if there is a risk of reading stale data.

          • +
          +

          This policy is based on the one in DataStax Java Driver. +The behaviour is the same.

          +
          +

          Examples

          +

          To use in Session:

          +
          use scylla::{Session, SessionBuilder};
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
          +
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .default_execution_profile_handle(handle)
          +    .build()
          +    .await?;
          +
          +
          +

          To use in a simple query:

          +
          use scylla::query::Query;
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
          +
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +
          +// Create a Query manually and set the retry policy
          +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
          +my_query.set_execution_profile_handle(Some(handle));
          +
          +// Run the query using this retry policy
          +let to_insert: i32 = 12345;
          +session.query(my_query, (to_insert,)).await?;
          +
          +
          +

          To use in a prepared query:

          +
          use scylla::prepared_statement::PreparedStatement;
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
          +
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +
          +// Create PreparedStatement manually and set the retry policy
          +let mut prepared: PreparedStatement = session
          +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
          +    .await?;
          +
          +prepared.set_execution_profile_handle(Some(handle));
          +
          +
          +// Run the query using this retry policy
          +let to_insert: i32 = 12345;
          +session.execute(&prepared, (to_insert,)).await?;
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/retry-policy/fallthrough.html b/v0.12.0/retry-policy/fallthrough.html new file mode 100644 index 0000000000..95879ce4a2 --- /dev/null +++ b/v0.12.0/retry-policy/fallthrough.html @@ -0,0 +1,693 @@ + + + + + + + + + + + + + Fallthrough retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Fallthrough retry policy

          +

          The FalthroughRetryPolicy never retries, returns errors straight to the user. Useful for debugging.

          +
          +

          Examples

          +

          To use in Session:

          +
          use scylla::{Session, SessionBuilder};
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::retry_policy::FallthroughRetryPolicy;
          +
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .default_execution_profile_handle(handle)
          +    .build()
          +    .await?;
          +
          +
          +

          To use in a simple query:

          +
          use scylla::query::Query;
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::retry_policy::FallthroughRetryPolicy;
          +
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +
          +// Create a Query manually and set the retry policy
          +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
          +my_query.set_execution_profile_handle(Some(handle));
          +
          +// Run the query using this retry policy
          +let to_insert: i32 = 12345;
          +session.query(my_query, (to_insert,)).await?;
          +
          +
          +

          To use in a prepared query:

          +
          use scylla::prepared_statement::PreparedStatement;
          +use scylla::transport::ExecutionProfile;
          +use scylla::transport::retry_policy::FallthroughRetryPolicy;
          +
          +let handle = ExecutionProfile::builder()
          +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
          +    .build()
          +    .into_handle();
          +
          +// Create PreparedStatement manually and set the retry policy
          +let mut prepared: PreparedStatement = session
          +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
          +    .await?;
          +
          +prepared.set_execution_profile_handle(Some(handle));
          +
          +// Run the query using this retry policy
          +let to_insert: i32 = 12345;
          +session.execute(&prepared, (to_insert,)).await?;
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/retry-policy/retry-policy.html b/v0.12.0/retry-policy/retry-policy.html new file mode 100644 index 0000000000..5eaab5aa58 --- /dev/null +++ b/v0.12.0/retry-policy/retry-policy.html @@ -0,0 +1,664 @@ + + + + + + + + + + + + + Retry policy configuration | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Retry policy configuration

          +

          After a query fails the driver might decide to retry it based on its Retry Policy and the query itself. +Retry policy can be configured for Session or just for a single query.

          +
          +

          Retry policies

          +

          By default there are three retry policies:

          + +

          It’s possible to implement a custom Retry Policy by implementing the traits RetryPolicy and RetrySession.

          +
          +
          +

          Query idempotence

          +

          A query is idempotent if it can be applied multiple times without changing the result of the initial application

          +

          Specifying that a query is idempotent increases the chances that it will be retried in case of failure. +Idempotent queries can be retried in situations where retrying non idempotent queries would be dangerous.

          +

          Idempotence has to be specified manually, the driver is not able to figure it out by itself.

          +
          use scylla::query::Query;
          +use scylla::prepared_statement::PreparedStatement;
          +
          +// Specify that a Query is idempotent
          +let mut my_query: Query = Query::new("SELECT a FROM ks.tab");
          +my_query.set_is_idempotent(true);
          +
          +
          +// Specify that a PreparedStatement is idempotent
          +let mut prepared: PreparedStatement = session
          +    .prepare("SELECT a FROM ks.tab")
          +    .await?;
          +
          +prepared.set_is_idempotent(true);
          +
          +
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/schema/schema.html b/v0.12.0/schema/schema.html new file mode 100644 index 0000000000..41600ece21 --- /dev/null +++ b/v0.12.0/schema/schema.html @@ -0,0 +1,679 @@ + + + + + + + + + + + + + Schema | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + +
          +

          Schema

          +

          The driver is capable of fetching database schema and presenting it to its users.

          +
          +

          Fetching schema

          +

          Fetching database schema occurs periodically, but it can also be done on-demand. In order to fetch the newest database schema, one can call refresh_metadata() on a Session instance:

          +
          #[tokio::main]
          +async fn main() -> Result<(), Box<dyn Error>> {
          +    let uri = std::env::var("SCYLLA_URI")
          +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
          +
          +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
          +    // Schema metadata will be fetched below
          +    session.refresh_metadata().await?;
          +    Ok(())
          +}
          +
          +
          +
          +
          +

          Inspecting schema

          +

          Once fetched, a snapshot of cluster’s schema can be examined. The following information can be obtained:

          +
            +
          • keyspace

            +
              +
            • tables belonging to the keyspace

            • +
            • materialized views belonging to the keyspace

            • +
            • replication strategy

            • +
            • user-defined types

            • +
            +
          • +
          • table/view

            +
              +
            • primary key definition

            • +
            • columns

            • +
            • partitioner type

            • +
            +
          • +
          +

          Example showing how to print obtained schema information:

          +
          #[tokio::main]
          +async fn main() -> Result<(), Box<dyn Error>> {
          +    let uri = std::env::var("SCYLLA_URI")
          +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
          +
          +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
          +    // Schema metadata will be fetched below
          +    session.refresh_metadata().await?;
          +
          +    let cluster_data = &session.get_cluster_data();
          +    let keyspaces = &cluster_data.get_keyspace_info();
          +
          +    for (keyspace_name, keyspace_info) in keyspaces.iter() {
          +        println!("Keyspace {}:", keyspace_name);
          +        println!("\tTables: {:#?}", keyspace_info.tables);
          +        println!("\tViews: {:#?}", keyspace_info.views);
          +        println!("\tUDTs: {:#?}", keyspace_info.user_defined_types);
          +    }
          +
          +    Ok(())
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/search.html b/v0.12.0/search.html new file mode 100644 index 0000000000..4228a42920 --- /dev/null +++ b/v0.12.0/search.html @@ -0,0 +1,598 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + + + + + +
          + + + + + +
          + + +
          + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/searchindex.js b/v0.12.0/searchindex.js new file mode 100644 index 0000000000..3ce75a51fa --- /dev/null +++ b/v0.12.0/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["connecting/authentication", "connecting/compression", "connecting/connecting", "connecting/tls", "contents", "data-types/blob", "data-types/collections", "data-types/counter", "data-types/data-types", "data-types/date", "data-types/decimal", "data-types/duration", "data-types/inet", "data-types/primitive", "data-types/text", "data-types/time", "data-types/timestamp", "data-types/timeuuid", "data-types/tuple", "data-types/udt", "data-types/uuid", "data-types/varint", "execution-profiles/create-and-use", "execution-profiles/execution-profiles", "execution-profiles/maximal-example", "execution-profiles/priority", "execution-profiles/remap", "index", "load-balancing/default-policy", "load-balancing/load-balancing", "logging/logging", "metrics/metrics", "migration-guides/0.11-serialization", "migration-guides/migration-guides", "queries/batch", "queries/lwt", "queries/paged", "queries/prepared", "queries/queries", "queries/result", "queries/schema-agreement", "queries/simple", "queries/timeouts", "queries/usekeyspace", "queries/values", "quickstart/create-project", "quickstart/example", "quickstart/quickstart", "quickstart/scylla-docker", "retry-policy/default", "retry-policy/downgrading-consistency", "retry-policy/fallthrough", "retry-policy/retry-policy", "schema/schema", "speculative-execution/percentile", "speculative-execution/simple", "speculative-execution/speculative", "tracing/basic", "tracing/paged", "tracing/prepare", "tracing/query-history", "tracing/tracing"], "filenames": ["connecting/authentication.md", "connecting/compression.md", "connecting/connecting.md", "connecting/tls.md", "contents.rst", "data-types/blob.md", "data-types/collections.md", "data-types/counter.md", "data-types/data-types.md", "data-types/date.md", "data-types/decimal.md", "data-types/duration.md", "data-types/inet.md", "data-types/primitive.md", "data-types/text.md", "data-types/time.md", "data-types/timestamp.md", "data-types/timeuuid.md", "data-types/tuple.md", "data-types/udt.md", "data-types/uuid.md", "data-types/varint.md", "execution-profiles/create-and-use.md", "execution-profiles/execution-profiles.md", "execution-profiles/maximal-example.md", "execution-profiles/priority.md", "execution-profiles/remap.md", "index.md", "load-balancing/default-policy.md", "load-balancing/load-balancing.md", "logging/logging.md", "metrics/metrics.md", "migration-guides/0.11-serialization.md", "migration-guides/migration-guides.md", "queries/batch.md", "queries/lwt.md", "queries/paged.md", "queries/prepared.md", "queries/queries.md", "queries/result.md", "queries/schema-agreement.md", "queries/simple.md", "queries/timeouts.md", "queries/usekeyspace.md", "queries/values.md", "quickstart/create-project.md", "quickstart/example.md", "quickstart/quickstart.md", "quickstart/scylla-docker.md", "retry-policy/default.md", "retry-policy/downgrading-consistency.md", "retry-policy/fallthrough.md", "retry-policy/retry-policy.md", "schema/schema.md", "speculative-execution/percentile.md", "speculative-execution/simple.md", "speculative-execution/speculative.md", "tracing/basic.md", "tracing/paged.md", "tracing/prepare.md", "tracing/query-history.md", "tracing/tracing.md"], "titles": ["Authentication", "Compression", "Connecting to the cluster", "TLS", "<no title>", "Blob", "List, Set, Map", "Counter", "Data Types", "Date", "Decimal", "Duration", "Inet", "Bool, Tinyint, Smallint, Int, Bigint, Float, Double", "Ascii, Text, Varchar", "Time", "Timestamp", "Timeuuid", "Tuple", "User defined types", "Uuid", "Varint", "Creating a profile and setting it", "Execution profiles", "All options supported by a profile", "Priorities of execution settings", "Remapping execution profile handles", "Scylla Rust Driver", "DefaultPolicy", "Load balancing", "Logging", "Driver metrics", "Adjusting code to changes in serialization API introduced in 0.11", "Migration guides", "Batch statement", "Lightweight transaction (LWT) query", "Paged query", "Prepared query", "Making queries", "Query result", "Schema agreement", "Simple query", "Query timeouts", "USE keyspace", "Query values", "Creating a project", "Connecting and running a simple query", "Quick Start", "Running Scylla using Docker", "Default retry policy", "Downgrading consistency retry policy", "Fallthrough retry policy", "Retry policy configuration", "Schema", "Percentile speculative execution", "Simple speculative execution", "Speculative execution", "Tracing a simple/prepared/batch query", "Tracing a paged query", "Tracing Session::prepare", "Query Execution History", "Query tracing"], "terms": {"driver": [0, 1, 2, 3, 8, 19, 28, 29, 30, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 49, 50, 52, 53, 56, 61], "support": [0, 1, 2, 3, 9, 15, 16, 21, 28, 32, 38, 42, 61], "both": [0, 32], "usernam": [0, 2], "password": [0, 2], "defin": [0, 8, 26, 32, 35, 40, 53], "user": [0, 8, 10, 21, 28, 32, 51, 52, 53], "To": [0, 3, 10, 19, 21, 22, 28, 29, 30, 32, 37, 39, 41, 45, 48, 49, 50, 51, 54, 55, 60], "specifi": [0, 1, 2, 25, 28, 34, 37, 41, 44, 46, 52, 60], "method": [0, 2, 28, 29, 32, 43, 56], "sessionbuild": [0, 1, 2, 3, 22, 25, 26, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "scylla": [0, 1, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 32, 34, 35, 36, 37, 38, 39, 41, 42, 44, 45, 46, 47, 49, 50, 51, 52, 54, 55, 57, 58, 59, 60, 61], "session": [0, 1, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 29, 30, 31, 32, 34, 35, 36, 39, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61], "let": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 30, 31, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "new": [0, 1, 2, 3, 6, 12, 16, 22, 24, 25, 26, 28, 29, 30, 34, 35, 36, 40, 41, 42, 44, 45, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "known_nod": [0, 1, 2, 3, 22, 25, 26, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "127": [0, 1, 2, 3, 12, 22, 25, 26, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55, 60], "0": [0, 1, 2, 3, 7, 10, 12, 13, 16, 18, 22, 25, 26, 30, 33, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 53, 54, 55, 60], "1": [0, 1, 2, 3, 5, 6, 9, 11, 12, 15, 16, 18, 22, 25, 26, 28, 30, 32, 34, 36, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 53, 54, 55, 60], "9042": [0, 1, 2, 22, 25, 26, 30, 40, 42, 46, 48, 49, 50, 51, 53, 54, 55, 60], "myusernam": 0, "mypassword": 0, "build": [0, 1, 2, 3, 22, 24, 25, 26, 28, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "await": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 29, 30, 34, 35, 36, 37, 39, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "A": [0, 32, 34, 35, 44, 50, 52, 58, 60], "implement": [0, 28, 29, 34, 41, 44, 50, 52, 60], "authenticatorsess": 0, "an": [0, 1, 2, 3, 9, 13, 15, 16, 22, 23, 25, 27, 28, 29, 35, 36, 39, 40, 41, 44, 46, 49, 50, 56, 60], "instanc": [0, 2, 23, 28, 29, 40, 48, 53], "creat": [0, 2, 3, 19, 23, 29, 30, 34, 35, 37, 40, 41, 43, 46, 47, 49, 50, 51, 57, 58, 60], "per": [0, 2, 29, 42], "so": [0, 2, 3, 25, 26, 28, 29, 32, 35, 40, 42, 50], "also": [0, 2, 16, 19, 25, 26, 27, 28, 29, 32, 43, 44, 49, 50, 52, 53], "necessari": [0, 40], "authenticatorprovid": 0, "final": [0, 32, 60], "make": [0, 10, 21, 27, 29, 32, 35, 40, 44, 48, 50], "authenticator_provid": 0, "byte": 0, "bufmut": [0, 32], "bytesmut": 0, "async_trait": 0, "autherror": 0, "struct": [0, 7, 8, 19, 32, 37, 44, 60], "customauthent": 0, "impl": [0, 32], "handl": [0, 2, 19, 22, 23, 29, 39, 41, 49, 50, 51, 54, 55], "challeng": 0, "initi": [0, 29, 50, 52], "inform": [0, 2, 8, 16, 19, 29, 32, 34, 36, 41, 44, 50, 53, 60, 61], "contain": [0, 2, 27, 29, 34, 35, 39, 41, 46, 57, 58, 59, 61], "token": [0, 29, 34, 37, 41], "paramet": [0, 19, 35, 60], "protocol": [0, 32], "specif": [0, 25, 28, 29, 35, 61], "It": [0, 1, 3, 9, 15, 16, 28, 29, 32, 35, 36, 39, 42, 43, 49, 50, 52, 55, 61], "mai": [0, 28, 32, 42, 50], "null": [0, 19], "empti": [0, 34, 36, 41, 44], "async": [0, 1, 2, 30, 36, 45, 46, 53], "fn": [0, 1, 2, 30, 32, 45, 46, 53], "evaluate_challeng": 0, "mut": [0, 3, 6, 22, 24, 25, 26, 32, 34, 35, 36, 37, 41, 42, 44, 49, 50, 51, 52, 57, 58, 59, 60], "self": [0, 2, 32], "_token": 0, "option": [0, 19, 23, 25, 27, 32, 35, 39, 41, 44, 57], "u8": [0, 5, 8], "result": [0, 1, 2, 8, 19, 30, 32, 34, 36, 37, 38, 42, 44, 46, 52, 53, 59, 60], "vec": [0, 5, 6, 8, 10, 39, 41], "err": [0, 40], "expect": [0, 16, 32], "to_str": [0, 1, 2, 6, 14, 18, 19, 28, 30, 35, 42, 44, 46, 53], "success": [0, 29, 37, 52, 60], "phase": 0, "exchang": 0, "request": [0, 2, 22, 23, 25, 28, 29, 31, 32, 34, 36, 41, 42, 44, 50, 54, 59, 60], "ok": [0, 1, 2, 30, 40, 46, 50, 53], "customauthenticatorprovid": 0, "start_authentication_sess": 0, "_name": 0, "str": [0, 8, 10, 14, 21, 32, 44], "box": [0, 1, 2, 24, 30, 46, 49, 50, 51, 53], "dyn": [0, 1, 2, 30, 46, 53], "respons": [0, 28, 32, 38, 39, 42, 60], "cred": 0, "0cassandra": 0, "cred_length": 0, "20": 0, "put_i32": 0, "put_slic": 0, "as_byt": 0, "some": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 35, 36, 37, 39, 40, 41, 42, 44, 46, 49, 50, 51, 52, 54, 55, 57, 58, 60, 61], "to_vec": 0, "authentication_exampl": 0, "error": [0, 1, 2, 15, 29, 30, 31, 39, 42, 46, 51, 52, 53, 60], "_session": 0, "arc": [0, 2, 24, 29, 49, 54, 55, 60], "By": [1, 2, 28, 32, 34, 37, 41, 44, 50, 52], "default": [1, 2, 19, 22, 24, 25, 28, 29, 30, 34, 35, 37, 40, 41, 42, 44, 52, 56, 57], "doe": [1, 32, 41, 42, 55, 60, 61], "us": [1, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 40, 41, 42, 44, 45, 46, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61], "ani": [1, 2, 9, 10, 15, 16, 19, 21, 23, 25, 31, 32, 35, 36, 37, 60, 61], "connect": [1, 27, 29, 30, 43, 59], "": [1, 2, 3, 9, 15, 16, 19, 25, 26, 28, 29, 32, 34, 35, 36, 37, 39, 41, 43, 44, 48, 52, 53, 60, 61], "possibl": [1, 28, 29, 32, 34, 36, 39, 42, 43, 52, 60, 61], "prefer": [1, 25, 36, 43], "algorithm": 1, "The": [1, 2, 3, 8, 19, 23, 28, 29, 30, 32, 35, 39, 40, 41, 42, 43, 48, 49, 50, 51, 53, 55, 60, 61], "try": [1, 2, 28, 29, 50, 60], "databas": [1, 2, 3, 8, 15, 16, 19, 27, 29, 32, 41, 44, 53, 61], "doesn": [1, 2, 3, 16, 37, 38, 60, 61], "t": [1, 2, 3, 6, 7, 8, 15, 16, 32, 36, 37, 38, 39, 40, 41, 43, 60, 61], "fall": [1, 28, 42], "back": [1, 42], "avail": [1, 9, 15, 16, 21, 25, 28, 30, 38, 55, 56, 61], "snappi": 1, "lz4": 1, "exampl": [1, 2, 3, 8, 19, 27, 29, 30, 32, 34, 37, 41, 43, 44, 46, 47, 53], "enabl": [1, 9, 10, 15, 16, 21, 26, 28, 29, 38, 56, 57, 58, 59, 60], "transport": [1, 22, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55, 58], "std": [1, 2, 3, 6, 8, 10, 12, 21, 22, 24, 28, 29, 30, 42, 46, 53, 54, 55, 60], "tokio": [1, 2, 30, 45, 46, 53], "main": [1, 2, 30, 45, 46, 53], "uri": [1, 2, 29, 30, 42, 46, 53], "env": [1, 2, 30, 42, 45, 46, 53], "var": [1, 2, 30, 42, 46, 53], "scylla_uri": [1, 2, 30, 42, 46, 53], "unwrap_or_els": [1, 2, 30, 42, 46, 53], "_": [1, 2, 30, 32, 36, 42, 46, 53], "i": [2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 23, 25, 27, 28, 29, 30, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 48, 49, 50, 52, 53, 54, 56, 58, 59, 60, 61], "distribut": [2, 28], "which": [2, 3, 10, 17, 21, 23, 25, 28, 29, 30, 32, 34, 36, 37, 39, 40, 41, 44, 46, 57, 60, 61], "mean": [2, 28, 29, 32, 36, 44, 48], "oper": [2, 28, 31, 34, 42, 44, 50, 61], "multipl": [2, 38, 52, 56, 58], "node": [2, 29, 34, 36, 37, 40, 41, 42, 46, 50, 56, 60, 61], "run": [2, 23, 27, 30, 34, 37, 38, 43, 45, 47, 49, 50, 51, 60], "independ": 2, "when": [2, 19, 27, 28, 29, 32, 35, 37, 38, 39, 41, 42, 43, 44, 49, 54, 60, 61], "you": [2, 3, 19, 25, 26, 28, 29, 30, 32, 34, 37, 38, 40, 41, 44, 49, 50, 61], "can": [2, 5, 7, 9, 10, 15, 16, 19, 21, 23, 25, 26, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 48, 49, 50, 52, 53, 56, 60, 61], "few": [2, 27, 39, 44, 47], "known": 2, "time": [2, 8, 22, 24, 28, 32, 40, 41, 42, 52, 54, 55, 60], "durat": [2, 8, 22, 24, 28, 40, 42, 54, 55], "net": [2, 8, 12], "ipaddr": [2, 8, 12], "ipv4addr": [2, 12], "socketaddr": 2, "72": 2, "4321": 2, "localhost": 2, "8000": 2, "connection_timeout": 2, "from_sec": [2, 22, 24, 28, 40, 42], "3": [2, 5, 6, 8, 9, 10, 11, 15, 21, 24, 28, 32, 34, 42, 44, 45, 50, 54, 55], "cluster_metadata_refresh_interv": 2, "10": [2, 3], "known_node_addr": 2, "v4": [2, 12], "9000": 2, "after": [2, 19, 28, 32, 40, 48, 52, 55, 61], "successfulli": [2, 29], "fetch": [2, 27, 36, 41, 58, 61], "topologi": 2, "about": [2, 8, 27, 29, 32, 34, 41, 44, 48, 60, 61], "other": [2, 9, 15, 16, 19, 28, 29, 32, 35, 37, 43, 50, 60], "thi": [2, 19, 23, 26, 27, 28, 29, 30, 32, 34, 36, 37, 38, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 60, 61], "them": [2, 25, 27, 28, 32, 34, 37, 38, 39, 41, 44, 46, 60], "well": [2, 28], "alwai": [2, 25, 35, 37, 50], "onli": [2, 7, 9, 15, 16, 28, 29, 32, 34, 35, 37, 40, 41, 56], "singl": [2, 23, 32, 36, 38, 39, 41, 44, 46, 52, 60], "object": [2, 23, 34], "apllic": 2, "becaus": [2, 3, 29, 36, 41], "veri": [2, 10, 21, 28, 32], "expens": 2, "maintain": 2, "its": [2, 9, 23, 28, 29, 32, 34, 52, 53, 56, 60], "own": [2, 19, 29], "pool": 2, "each": [2, 8, 28, 29, 32, 34, 36, 41, 44, 46, 58, 59, 60], "capabl": [2, 53], "parallel": [2, 38, 60], "rout": [2, 28], "shard": [2, 34, 37, 41], "actual": [2, 32, 42], "data": [2, 19, 27, 28, 29, 32, 34, 37, 41, 50], "unless": [2, 28, 32, 50], "load": [2, 23, 27, 28, 34, 37, 38, 41], "balanc": [2, 23, 27, 28, 34, 37, 38, 41], "polici": [2, 23, 27, 28, 54, 55, 60], "For": [2, 3, 19, 29, 32, 34, 35, 36, 37, 39, 40, 41, 43, 50], "those": [2, 25, 28, 32], "reason": [2, 32, 50], "we": [2, 5, 26, 32, 37, 40, 43, 44, 47, 48, 50, 60, 61], "recommend": [2, 28, 29, 32, 50], "one": [2, 19, 21, 25, 32, 34, 36, 37, 39, 42, 43, 49, 50, 53, 55, 60], "applic": [2, 28, 40, 42, 52], "short": 2, "live": [2, 50], "e": [2, 9, 28, 29, 32, 35, 40, 42], "g": [2, 28, 29, 32, 35, 40], "strongli": [2, 34], "discourag": [2, 34], "great": 2, "perform": [2, 28, 29, 32, 38, 40, 44, 58, 60, 61], "penalti": [2, 36], "costli": 2, "process": [2, 42], "requir": [2, 9, 16, 19, 32, 35, 36, 41, 44, 48, 50], "estabilish": 2, "lot": [2, 40], "tcp": 2, "mani": [2, 34, 38, 60], "thread": 2, "task": 2, "wast": 2, "resourc": 2, "mention": [2, 32], "befor": [2, 9, 28, 32, 34, 37, 38, 40, 56], "itself": [2, 32, 35, 39, 52], "queri": [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 40, 47, 48, 49, 50, 51, 55, 56, 59], "would": [2, 32, 52, 60, 61], "hold": 2, "unnecessarili": 2, "If": [2, 9, 15, 16, 28, 29, 32, 36, 37, 40, 41, 42, 43, 44, 50, 58, 59, 61], "need": [2, 3, 29, 36, 37, 38, 39, 40, 41, 43, 48, 61], "share": [2, 23, 54], "differ": [2, 9, 15, 16, 19, 23, 27, 35, 43, 44], "etc": [2, 27, 60, 61], "all": [2, 16, 22, 23, 26, 27, 28, 30, 32, 34, 37, 38, 40, 41, 52, 58, 59, 60, 61], "take": [2, 32, 34, 36, 37, 41], "hinder": 2, "function": [2, 3, 38, 40], "wai": [2, 23, 26, 36, 37, 39, 41, 48, 61], "refresh": 2, "period": [2, 53], "schema": [2, 27, 32], "everi": [2, 28, 40], "60": 2, "second": [2, 15, 16, 32, 34, 42, 43, 56], "howev": [2, 9, 15, 16, 32, 40, 42, 60], "set": [2, 8, 23, 27, 28, 29, 32, 34, 35, 37, 41, 42, 43, 47, 49, 50, 51, 61], "non": [2, 28, 34, 35, 36, 52, 55, 56, 60], "neg": [2, 15], "valu": [2, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 28, 35, 36, 37, 40, 43, 46, 49, 50, 51, 57, 58, 61], "do": [2, 27, 29, 32, 34, 40, 50, 60], "have": [2, 3, 19, 25, 26, 29, 30, 32, 34, 35, 36, 37, 39, 40, 42, 44, 50], "unexpect": 2, "amount": [2, 37, 41, 60], "traffic": [2, 28], "extra": [2, 9, 15, 16], "caus": [2, 29, 37, 41], "chang": [2, 19, 23, 26, 33, 34, 35, 37, 40, 41, 44, 52, 60], "frequent": 2, "elast": 2, "dynam": 2, "deploy": 2, "model": 2, "secur": 2, "bundl": 2, "follow": [2, 8, 9, 15, 16, 17, 23, 24, 25, 26, 28, 32, 50, 53, 61], "path": [2, 3], "cloudsessionbuild": 2, "config_data": 2, "yaml": 2, "unwrap": [2, 9, 15, 16, 31, 39], "note": [2, 19, 28, 32, 34, 37, 42, 50], "file": [2, 3], "provid": [2, 29, 32, 37, 39, 42, 44, 60, 61], "here": [2, 28, 39, 41, 46, 60], "configur": [2, 23, 27, 28, 30, 32, 56], "datacent": [2, 35, 50], "datacenter1": 2, "certificateauthoritydata": 2, "certificate_data": 2, "server": [2, 42], "9142": [2, 3], "nodedomain": 2, "cql": [2, 8, 19, 32, 35, 43, 48], "id": [2, 57, 58, 59, 61], "com": 2, "insecureskiptlsverifi": 2, "fals": [2, 28, 40, 43], "authinfo": 2, "clientcertificatedata": 2, "clientkeydata": 2, "key_data": 2, "scylladb": [2, 42, 48], "context": 2, "datacenternam": 2, "authinfonam": 2, "currentcontext": 2, "openssl": 3, "crate": [3, 10, 30, 32, 60], "wa": [3, 19, 29, 37, 39, 50, 57, 61], "chosen": 3, "rustl": 3, "certif": 3, "ip": [3, 11, 12], "address": [3, 11, 12, 28], "see": [3, 8, 9, 15, 16, 19, 26, 29, 32, 34, 35, 37, 39, 41, 43, 44, 50, 60], "issu": [3, 32, 36, 44], "common": [3, 23, 29], "case": [3, 9, 15, 16, 25, 28, 29, 32, 36, 37, 40, 41, 50, 52, 60], "pure": 3, "rust": [3, 8, 13, 18, 19, 28, 32, 35, 39, 41, 44, 47], "librari": 3, "instal": [3, 30, 47, 48], "proper": 3, "packag": 3, "add": [3, 34, 45], "cargo": [3, 30, 45], "toml": [3, 45], "version": [3, 27, 32, 33, 40, 45], "4": [3, 5, 6, 8, 16, 21, 32, 34, 45, 57, 58], "ssl": 3, "32": [3, 10], "Then": 3, "debian": 3, "ubuntu": 3, "apt": 3, "libssl": 3, "dev": 3, "pkg": 3, "config": 3, "fedora": 3, "dnf": 3, "devel": 3, "arch": 3, "pacman": 3, "sslcontext": 3, "pass": [3, 29, 34, 37, 41, 44, 60], "ca": 3, "crt": 3, "sslcontextbuild": 3, "sslmethod": 3, "sslverifymod": 3, "pathbuf": 3, "context_build": 3, "set_ca_fil": 3, "set_verifi": 3, "peer": 3, "port": 3, "now": [3, 19, 26, 32, 43, 45, 46, 58, 59], "ssl_context": 3, "full": [3, 9, 16, 30, 45], "more": [3, 8, 9, 15, 16, 19, 32, 34, 35, 36, 37, 39, 40, 41, 42, 44, 50, 52, 60, 61], "detail": [3, 29], "repres": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 32, 39, 41, 60], "intotypedrow": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 36, 39, 41, 46], "insert": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 34, 35, 37, 39, 41, 43, 44, 46, 49, 50, 51, 57, 58], "tabl": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 32, 35, 36, 37, 40, 41, 42, 43, 46, 53, 61], "refer": [5, 28, 29, 32, 44], "move": 5, "whole": [5, 34, 36, 56], "to_insert": [5, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 35, 37, 41, 46, 49, 50, 51], "2": [5, 6, 9, 11, 15, 32, 34, 36, 41, 44, 48, 50], "5": [5, 6, 32, 34], "INTO": [5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 34, 35, 37, 39, 41, 43, 44, 46, 49, 50, 51, 57, 58], "keyspac": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 30, 38, 40, 41, 42, 46, 53], "read": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 38, 41, 46, 50, 60], "from": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 29, 30, 36, 37, 39, 41, 43, 44, 46, 52, 57, 58, 59, 60, 61], "row": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 36, 41, 43, 46, 58], "select": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 32, 36, 39, 41, 43, 46, 52, 57, 58, 59, 60], "into_typ": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 36, 41, 46], "blob_valu": 5, "int": [6, 8, 18, 19, 32, 37, 39, 44, 46], "my_list": 6, "i32": [6, 8, 13, 18, 19, 32, 35, 36, 37, 39, 41, 44, 46, 49, 50, 51], "list_valu": 6, "hashset": 6, "btreeset": 6, "my_set": 6, "set_valu": 6, "collect": [6, 8], "into_it": 6, "hashmap": [6, 8, 44], "k": [6, 8, 19, 22, 24, 25, 26, 30, 34, 35, 36, 37, 39, 41, 44, 46, 49, 50, 51, 52, 57, 58, 59, 60], "v": [6, 8], "btreemap": 6, "text": [6, 8, 19, 34, 37, 39, 41, 44], "my_map": 6, "string": [6, 8, 14, 18, 19, 32, 35, 37, 39, 41, 44], "abcd": 6, "16": [6, 18, 34, 36, 37, 44], "map_valu": 6, "pub": [7, 32], "i64": [7, 8, 13, 15, 16], "updat": [7, 27, 29, 34, 40], "frame": [7, 9, 10, 11, 15, 16, 17, 39, 44], "c": [7, 36, 37, 41, 44, 48], "counter_valu": 7, "counter_int_valu": 7, "map": [8, 26, 44], "match": [8, 9, 15, 16, 19, 32, 39, 41, 44], "achiev": [8, 43, 50], "seamless": 8, "send": [8, 29, 32, 34, 36, 41, 43, 44, 60, 61], "receiv": [8, 19, 30, 32, 36, 37, 39, 41, 48, 58], "chapter": [8, 47, 61], "how": [8, 27, 36, 53, 61], "equival": [8, 32], "boolean": 8, "bool": 8, "tinyint": 8, "i8": [8, 13], "smallint": 8, "i16": [8, 13, 32], "bigint": [8, 45], "float": 8, "f32": [8, 13], "doubl": 8, "f64": [8, 13], "ascii": 8, "varchar": 8, "counter": 8, "blob": 8, "inet": [8, 11], "uuid": [8, 17, 45, 57, 58, 59], "timeuuid": 8, "cqltimeuuid": [8, 17], "date": [8, 16], "cqldate": 8, "chrono": 8, "naived": [8, 16], "cqltime": 8, "naivetim": [8, 16], "timestamp": [8, 60], "cqltimestamp": 8, "datetim": 8, "utc": [8, 16, 60], "offsetdatetim": 8, "cqldurat": [8, 11], "decim": 8, "cqldecim": 8, "bigdecim": [8, 45], "varint": 8, "cqlvarint": 8, "num_bigint": 8, "v0": [8, 21], "list": [8, 29, 34, 41, 44, 58, 59, 60], "tupl": [8, 34, 39, 41, 44, 46], "udt": [8, 19, 32], "custom": [8, 17, 19, 29, 37, 41, 42, 44, 52], "macro": [8, 19, 39, 44], "depend": [9, 15, 16, 36, 45], "featur": [9, 10, 15, 16, 21, 45, 61], "flag": [9, 10, 15, 16, 21, 28, 61], "three": [9, 15, 16, 25, 28, 32, 44, 50, 52], "type": [9, 10, 15, 16, 21, 27, 32, 35, 38, 41, 53], "interact": [9, 10, 15, 16, 21], "intern": [9, 15, 16, 29], "number": [9, 10, 15, 16, 21, 27, 31, 32, 34, 39, 50], "dai": [9, 11], "sinc": [9, 15, 16], "5877641": 9, "06": 9, "23": [9, 15], "31": 9, "unix": [9, 16], "epoch": [9, 16], "without": [9, 10, 15, 16, 19, 21, 32, 39, 40, 43, 52, 60], "u32": 9, "wrapper": [9, 10, 15, 16, 17, 21, 32], "represent": [9, 15, 16, 32, 60], "most": [9, 15, 16, 29, 55], "ar": [9, 14, 15, 16, 19, 23, 25, 26, 28, 29, 32, 34, 36, 37, 38, 39, 41, 43, 44, 50, 52, 56, 58, 59, 61], "practic": [9, 15, 16, 32], "section": [9, 15, 16, 32, 37], "1970": [9, 16], "01": [9, 15, 16], "08": [9, 60], "7": [9, 36], "raw": [9, 32, 43], "date_valu": 9, "rang": [9, 16, 28], "262145": 9, "262143": 9, "12": [9, 45], "2021": 9, "03": [9, 15, 21], "24": 9, "from_ymd_opt": [9, 16], "altern": [9, 16], "document": [9, 19, 34, 35, 37, 41, 44, 50], "get": [9, 39, 60, 61], "info": [9, 16, 30, 57, 58, 59], "month": [9, 11, 16], "from_calendar_d": [9, 16], "march": 9, "simpl": [10, 21, 27, 32, 34, 36, 37, 38, 47, 49, 50, 51, 56, 58], "sign": [10, 21], "binari": [10, 21], "big": [10, 21, 36], "endian": [10, 21], "order": [10, 17, 19, 21, 32, 36, 41, 44, 53, 60], "bit": [10, 39], "scale": 10, "fromstr": [10, 21], "123": [10, 13, 16], "456": [10, 15], "from_signed_be_bytes_and_expon": 10, "0x01": 10, "0xe2": 10, "0x40": 10, "decimal_valu": 10, "should": [10, 21, 30, 32, 41, 44, 45, 48], "04": [10, 16, 21], "from_str": [10, 17, 21], "12345": [10, 13, 21, 35, 37, 41, 43, 46, 49, 50, 51], "nanosecond": [11, 15], "cql_durat": 11, "inet_valu": 12, "true": [13, 28, 43, 52, 57, 58, 59], "bool_valu": 13, "tinyint_valu": 13, "smallint_valu": 13, "int_valu": [13, 18, 39], "bigint_valu": 13, "float_valu": 13, "double_valu": 13, "to_insert_str": 14, "abcdef": 14, "text_valu": [14, 39], "midnight": 15, "exce": 15, "86399999999999": 15, "59": 15, "999999999": 15, "64": [15, 16], "1_000_000_000": 15, "time_valu": 15, "although": [15, 27], "leap": 15, "thei": [15, 19, 21, 28, 29, 31, 32, 34, 37, 41, 44], "attempt": [15, 60, 61], "convert": [15, 16, 29, 39, 60], "write": [15, 16, 19, 28, 43, 50], "return": [15, 16, 28, 29, 32, 36, 37, 39, 40, 41, 42, 50, 51, 52, 57], "02": 15, "789": 15, "012": 15, "from_hms_nano_opt": 15, "456_789_012": 15, "from_hms_nano": 15, "describ": [16, 26, 32], "millisecond": [16, 40], "accept": 16, "00": 16, "1000": 16, "timestamp_valu": 16, "timezon": 16, "explicitli": 16, "store": [16, 28], "precis": 16, "finer": 16, "than": [16, 28, 37, 39, 40, 42, 43, 44, 50], "1m": 16, "lost": 16, "naivedatetim": 16, "from_hms_milli_opt": 16, "and_utc": 16, "As": [16, 26, 28, 32, 41, 42], "correct": [16, 28, 32], "eras": 16, "On": [16, 29, 36, 50], "primitivedatetim": 16, "januari": 16, "from_hms_milli": 16, "assume_utc": 16, "logic": [17, 42], "cassandra": [17, 27, 29, 42, 61], "semant": 17, "8e14e760": [17, 20], "7fa8": [17, 20], "11eb": [17, 20], "bc66": [17, 20], "000000000001": [17, 20], "timeuuid_valu": 17, "max": [18, 44], "element": [18, 29, 44], "abc": 18, "tuple_valu": 18, "string_valu": 18, "allow": [19, 23, 28, 29, 32, 34, 36, 38, 43, 60, 61], "name": [19, 32, 39, 43, 44], "field": [19, 28, 32, 39, 44], "offici": 19, "correspond": [19, 50], "sai": [19, 37, 61], "my_typ": 19, "int_val": 19, "text_val": 19, "deriv": [19, 32, 39, 44], "serializecql": 19, "abl": [19, 28, 29, 52, 60], "same": [19, 28, 29, 32, 35, 36, 37, 39, 43, 44, 49, 50, 60, 61], "renam": 19, "attribut": [19, 32, 44], "fromusertyp": [19, 32], "mismatch": 19, "between": [19, 23, 34], "temporari": 19, "situat": [19, 52], "futur": [19, 29, 32, 36, 40, 45, 58], "replac": [19, 32], "earlier": 19, "must": [19, 28, 32, 34, 37, 39, 44], "wrap": [19, 32, 43], "gracefulli": 19, "debug": [19, 51], "mytyp": 19, "import": [19, 35], "deseri": [19, 32], "de": 19, "serial": [19, 23, 24, 33, 35, 36, 41], "anoth": [19, 22, 23, 26, 32, 50, 55, 56, 60], "look": [19, 32], "behaviour": [19, 40, 49, 50], "sent": [19, 29, 32, 34, 37, 41, 44, 60, 61], "just": [19, 30, 32, 34, 35, 36, 37, 43, 44, 52, 60], "like": [19, 34, 35, 36, 37, 48, 60, 61], "cql_to_rust": [19, 39], "fromcqlval": 19, "17": [19, 44, 48], "my_type_valu": 19, "parse_str": 20, "uuid_valu": 20, "num": [21, 45], "accordingli": 21, "varint_valu": 21, "executionprofil": [22, 23, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55], "attach": 22, "statement": [22, 23, 24, 25, 26, 28, 32, 35, 37, 38, 41, 42, 57], "consist": [22, 23, 24, 25, 26, 28, 34, 35, 37, 41, 52, 60], "builder": [22, 24, 25, 26, 28, 29, 42, 49, 50, 51, 54, 55], "localon": 22, "request_timeout": [22, 24, 42], "none": [22, 28, 29, 42, 44], "timeout": [22, 23, 25, 40, 50], "into_handl": [22, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55], "default_execution_profile_handl": [22, 25, 26, 29, 42, 49, 50, 51, 54, 55], "30": [22, 24, 28, 42], "query1": [22, 26], "set_execution_profile_handl": [22, 24, 25, 26, 42, 49, 50, 51], "clone": [22, 25, 26, 36, 60], "query2": [22, 26], "pk": [22, 26, 32], "where": [22, 26, 32, 36, 40, 41, 50, 52, 56], "base": [22, 28, 29, 30, 32, 49, 50, 52], "base_profil": 22, "to_build": 22, "group": [23, 27, 28], "variou": [23, 27, 31, 34], "togeth": [23, 27], "workload": [23, 26, 28], "conveni": [23, 26, 35], "encapsul": 23, "retri": [23, 27, 31, 40, 60, 61], "specul": [23, 29, 61], "There": [23, 28, 56, 61], "two": [23, 25, 26, 29, 32, 34, 35, 39, 43, 48, 50, 61], "class": [23, 30, 46], "relat": 23, "executionprofilehandl": [23, 26], "former": 23, "simpli": [23, 29, 41, 44, 60], "immut": 23, "latter": 23, "particular": [23, 28, 29], "moment": [23, 31], "point": 23, "dure": [23, 31, 32, 56], "lifetim": 23, "assign": [23, 25, 26, 28], "At": 23, "remap": 23, "switch": [23, 26, 27], "characterist": 23, "speculative_execut": [24, 54, 55], "simplespeculativeexecutionpolici": [24, 55], "serialconsist": [24, 35], "load_balanc": [24, 28, 29], "defaultpolici": [24, 29], "retry_polici": [24, 49, 50, 51], "fallthroughretrypolici": [24, 51], "sync": [24, 29, 32, 54, 55, 60], "serial_consist": 24, "load_balancing_polici": [24, 29], "speculative_execution_polici": [24, 54, 55], "max_retry_count": [24, 54, 55], "retry_interv": [24, 55], "from_milli": [24, 55], "100": [24, 55], "profil": [25, 27, 29, 49], "either": [25, 60], "overridden": 25, "upon": [25, 40], "creation": [25, 56], "moreov": 25, "ha": [25, 28, 32, 41, 43, 50, 52, 54, 56, 60, 61], "higher": 25, "directli": [25, 32], "In": [25, 28, 29, 32, 36, 37, 41, 43, 45, 47, 50, 53, 60], "over": [25, 32, 36], "recap": 25, "session_profil": 25, "One": [25, 26, 34, 35, 37, 41, 50], "query_profil": 25, "appli": [25, 28, 32, 52], "therefor": [25, 40, 43, 50], "set_consist": [25, 34, 35, 37, 41], "affect": [26, 28, 32, 36, 41], "been": [26, 40, 50], "quick": [26, 27], "session1": 26, "handle1": 26, "profile1": 26, "statement1": 26, "statement2": 26, "handle2": 26, "profile2": 26, "becom": [26, 28, 35], "yield": [26, 42], "power": 26, "modifi": [26, 34], "your": [26, 29, 36, 44], "below": [26, 32, 42, 50, 53], "abov": [26, 28, 54], "code": [26, 27, 29], "map_to_another_profil": 26, "book": 27, "written": [27, 30, 32], "optim": [27, 29, 56], "compat": [27, 32], "apach": 27, "lesson": 27, "univers": 27, "api": [27, 34, 35, 37, 41], "start": [27, 30, 36, 48, 55, 56, 60], "up": [27, 43, 47, 50], "project": [27, 47], "migrat": [27, 40], "guid": 27, "older": 27, "cluster": [27, 28, 29, 36, 37, 41, 50, 53], "prepar": [27, 28, 29, 36, 38, 41, 49, 50, 51, 52, 58, 61], "batch": [27, 32, 35, 38, 61], "page": [27, 31, 32, 37, 38, 41], "execut": [27, 28, 29, 30, 32, 34, 36, 39, 40, 41, 42, 49, 50, 51, 57], "onc": [27, 32, 34, 38, 53, 60], "column": [27, 32, 39, 44, 53], "what": [27, 43, 60, 61], "fail": [27, 29, 32, 39, 50, 52, 60], "idempot": 27, "metric": [27, 54], "statist": [27, 29], "latenc": [27, 29, 31, 43, 56], "log": [27, 50], "view": [27, 30, 53], "integr": 27, "produc": [27, 32], "trace": [27, 30, 45, 60], "inspect": 27, "local": [28, 35, 42], "mode": 28, "defaultpolicybuild": 28, "rack": 28, "is_token_awar": 28, "permit_dc_failov": 28, "latency_awar": 28, "desir": 28, "default_polici": 28, "prefer_datacenter_and_rack": 28, "dc1": 28, "rack1": 28, "token_awar": 28, "priorit": 28, "locat": 28, "my_dc": 28, "treat": [28, 44], "remot": 28, "zone": 28, "too": 28, "first": [28, 29, 32, 34, 36, 37, 39, 43, 55, 56, 60], "replica": [28, 29, 50], "similarli": 28, "disabl": [28, 29, 32, 40], "includ": [28, 29, 32, 34, 47, 60], "exclud": 28, "even": [28, 34, 50], "aliv": [28, 50], "serv": 28, "event": [28, 57, 58, 59, 60, 61], "outag": 28, "network": 28, "failur": [28, 29, 40, 52], "unavail": [28, 50], "client": [28, 48], "longer": 28, "access": [28, 31, 43, 54, 60], "permit": 28, "due": [28, 34], "constraint": 28, "mechan": [28, 40], "partit": [28, 37], "across": 28, "want": [28, 32, 40, 44], "being": [28, 29, 32, 34, 39, 50], "help": [28, 29, 39, 49], "minim": 28, "improv": 28, "ensur": [28, 32, 39], "much": [28, 32, 37], "within": [28, 35], "assum": 28, "significantli": 28, "scalabl": 28, "built": [28, 32], "reduc": 28, "overhead": [28, 32], "throughput": 28, "pleas": [28, 35, 48], "penalis": 28, "whose": 28, "measur": 28, "recent": 28, "averag": [28, 31], "classifi": 28, "behind": 28, "update_r": 28, "global": [28, 30, 42], "minimum": 28, "comput": [28, 29, 37], "wors": [28, 43], "exclusion_threshold": 28, "retry_period": 28, "involv": 28, "put": [28, 34, 45], "end": [28, 43, 60], "often": 28, "truli": 28, "benefici": 28, "faster": 28, "lag": 28, "worsen": [28, 37, 41], "warn": [28, 30, 34, 36, 37, 41], "NOT": [28, 30, 35, 40, 46], "prior": 28, "benchmark": 28, "prove": 28, "impact": 28, "caution": 28, "latencyawarenessbuild": 28, "latency_awareness_build": 28, "minimum_measur": 28, "200": [28, 40], "further": 28, "customis": 28, "cours": 28, "prefer_datacent": 28, "down": [28, 29, 40], "And": 28, "ones": [28, 32, 61], "prioriti": 28, "shuffl": 28, "randomli": 28, "rotat": 28, "round": [28, 32, 36, 41], "robin": 28, "random": [28, 34, 41], "index": 28, "optimis": 28, "lwt": 28, "ring": 28, "prevent": 28, "content": 28, "paxo": 28, "conflict": 28, "determin": [29, 50], "contact": 29, "gener": [29, 30, 32, 44], "state": [29, 43], "influenc": 29, "open": 29, "blacklist": 29, "host_filt": 29, "hostfilt": 29, "wide": 29, "construct": 29, "essenti": [29, 32], "best": [29, 32, 34, 36, 43, 50], "might": [29, 32, 36, 37, 39, 40, 41, 44, 48, 49, 52, 60], "better": [29, 37, 38, 44, 50], "suit": 29, "our": [29, 32], "awar": [29, 34, 37, 41], "via": [29, 35], "sampl": [29, 60], "newli": [29, 32], "addit": [29, 32, 35, 36], "through": [29, 32], "level": [29, 35, 50], "basi": 29, "usual": 29, "unnecessari": 29, "entir": 29, "given": [29, 39, 42, 54], "call": [29, 32, 34, 53, 60], "iter": [29, 31, 36, 39, 53, 56, 58], "rest": [29, 35], "layer": 29, "filter": [29, 45], "out": [29, 52, 60], "feedback": 29, "health": 29, "decis": [29, 60, 61], "hand": 29, "messag": [29, 30, 48], "overload": 29, "avoid": [29, 39, 43], "again": [29, 32, 40], "until": [29, 42, 60], "recov": 29, "subscrib": [30, 45], "print": [30, 41, 45, 46, 53, 60], "collector": [30, 60], "rust_log": 30, "tracing_subscrib": 30, "fmt": 30, "init": 30, "IF": [30, 35, 46], "exist": [30, 32, 35, 46], "WITH": [30, 46], "replic": [30, 46, 53], "networktopologystrategi": [30, 46], "replication_factor": [30, 46], "folder": 30, "get_metr": 31, "total": 31, "nonpag": 31, "println": [31, 36, 40, 41, 45, 46, 53, 57, 58, 59, 60], "get_queries_num": 31, "get_queries_iter_num": 31, "occur": [31, 53], "get_errors_num": 31, "get_errors_iter_num": 31, "get_latency_avg_m": 31, "99": [31, 54], "9": 31, "percentil": [31, 56], "get_latency_percentile_m": 31, "bind": [32, 34, 44], "marker": [32, 34, 44], "untyp": 32, "form": 32, "safer": 32, "robust": 32, "interfac": 32, "check": [32, 44, 60], "against": [32, 56], "couldn": 32, "kind": 32, "valuelist": [32, 34], "serializedresult": 32, "write_to_request": 32, "buf": 32, "serializevalueserror": 32, "naiv": 32, "hope": [32, 60], "took": 32, "care": [32, 60], "db": 32, "side": [32, 42], "valid": 32, "worst": 32, "reinterpret": 32, "unintend": 32, "manner": 32, "problem": [32, 43], "robustli": 32, "intousertyp": 32, "cumbersom": 32, "deprec": 32, "fix": 32, "previou": [32, 36], "core": 32, "AND": 32, "ck": 32, "associ": 32, "legacybatchvalu": 32, "previous": 32, "batchvalu": [32, 34], "sourc": 32, "were": [32, 61], "notabl": [32, 35], "cach": [32, 34], "come": 32, "did": 32, "correctli": 32, "while": [32, 36, 58], "ergonom": 32, "counterpart": 32, "fromrow": [32, 39], "limit": [32, 40, 42], "properli": [32, 37, 38, 39], "similar": 32, "rework": 32, "plan": 32, "releas": 32, "worth": 32, "keep": 32, "bring": 32, "cannot": [32, 50], "right": 32, "shown": 32, "snippet": 32, "exact": 32, "effect": 32, "complet": [32, 42, 61], "analog": 32, "flavor": [32, 44], "enforce_ord": [32, 44], "skip_name_check": 32, "person": 32, "surnam": 32, "ag": [32, 39], "learn": 32, "consider": 32, "concern": 32, "cachingsess": [32, 37], "alreadi": 32, "explain": 32, "done": [32, 34, 53, 60], "unprepar": [32, 34, 36], "skip": [32, 44, 61], "detect": 32, "noth": [32, 50], "along": [32, 60], "slowdown": 32, "incur": 32, "trip": [32, 36, 41], "uniqu": 32, "roundtrip": [32, 43], "unaccept": 32, "beforehand": 32, "reus": 32, "align": 32, "sensit": 32, "easi": [32, 38], "occurr": [32, 50], "ad": [32, 41, 44], "atribut": 32, "procedur": 32, "larg": [32, 37, 41], "enough": 32, "codebas": 32, "complic": 32, "everyth": [32, 46], "remov": 32, "rather": [32, 40], "util": [32, 61], "newtyp": 32, "valueadapt": 32, "valuelistadapt": 32, "legacybatchvaluesadapt": 32, "zero": 32, "cost": 32, "alloc": 32, "buffer": 32, "rewritten": 32, "shouldn": 32, "effici": 32, "legacybatchvaluesiter": 32, "write_next_to_request": 32, "natur": 32, "safe": 32, "convers": 32, "direct": [32, 42], "respect": 32, "impl_serialize_cql_via_valu": 32, "impl_serialize_row_via_value_list": 32, "11": [33, 60], "These": 34, "delet": [34, 44], "prepared_stat": [34, 36, 37, 49, 50, 51, 52, 57, 58, 59], "preparedstat": [34, 35, 36, 37, 49, 50, 51, 52, 57, 58, 59], "append_stat": [34, 57], "tab": [34, 35, 37, 39, 41, 43, 44, 49, 50, 51, 52, 57, 58, 59], "b": [34, 36, 37, 39, 41, 43, 44], "manual": [34, 35, 41, 49, 50, 51, 52, 57, 58, 61], "6": [34, 36, 45], "bound": [34, 37, 41, 44], "batch_valu": 34, "5_i32": 34, "sequenti": [34, 60], "consid": 34, "instead": [34, 36, 37, 41, 43], "individu": 34, "simple_unprepared1": 34, "simple_unprepared2": 34, "prepared_batch": 34, "prepare_batch": 34, "1_i32": [34, 44], "2_i32": [34, 41, 44], "3_i32": 34, "4_i32": 34, "length": 34, "equal": 34, "trait": [34, 44, 52], "slice": [34, 44], "unit": [34, 44], "third": [34, 60], "express": 35, "serial_consistency_level": 35, "separ": [35, 61], "simplequeri": 35, "lai": 35, "condit": 35, "rememb": 35, "localseri": 35, "variant": [35, 36], "commonli": 35, "cross": 35, "overrid": 35, "ONE": [35, 41], "my_queri": [35, 41, 49, 50, 51, 52], "set_serial_consist": 35, "remain": 35, "ident": 35, "sometim": [36, 40, 50], "fit": [36, 38], "query_it": [36, 61], "execute_it": [36, 61], "fulli": [36, 38], "amort": 36, "stream": [36, 60], "streamext": [36, 58], "rows_stream": 36, "next_row_r": 36, "next": [36, 50, 58, 60], "set_page_s": 36, "extract": 36, "That": 36, "left": 36, "off": [36, 42], "paged_queri": 36, "with_page_s": 36, "res1": 36, "res2": 36, "query_pag": 36, "paging_st": 36, "paged_prepar": 36, "execute_pag": 36, "later": 37, "work": [37, 41], "kei": [37, 46, 53], "don": [37, 39, 41, 43], "unpag": [37, 41], "heavi": [37, 41], "size": [37, 41], "least": [37, 50], "succe": [37, 50, 60], "inherit": 37, "especi": 37, "good": 37, "otherwis": [37, 40, 50], "hash": 37, "wrong": 37, "prepare_t": 37, "primari": [37, 46, 53], "wrong_prepar": 37, "54321": [37, 43], "matter": [37, 41, 60], "good_prepar": 37, "poor": 38, "primit": 38, "fast": 38, "addition": [38, 41], "special": 38, "asynchron": 38, "wish": [38, 40, 42], "queryresult": [39, 41, 57], "awkward": 39, "as_ref": [39, 44], "as_int": 39, "rows_typ": 39, "rowt": 39, "maybe_first_row_typ": 39, "first_row_typ": 39, "maybe_first_row": 39, "single_row_typ": 39, "first_row": 39, "result_not_row": 39, "bug": [39, 40], "first_int_v": 39, "no_row": 39, "str_or_nul": 39, "myrow": 39, "my_row": 39, "agre": 40, "automat": 40, "alter": 40, "wait": [40, 60], "never": [40, 41, 44, 51, 52], "slow": 40, "somebodi": 40, "sens": 40, "said": 40, "auto_await_schema_agr": 40, "await_schema_agr": 40, "ed": 40, "long": 40, "won": 40, "forev": 40, "sessionconfig": 40, "elaps": 40, "queryerror": [40, 42], "requesttimeout": [40, 42], "schema_vers": 40, "sleep": 40, "schema_agreement_interv": 40, "check_schema_agr": 40, "is_som": 40, "els": 40, "IN": 40, "anyth": [41, 61], "Into": 41, "constant": [41, 44, 55], "variabl": [41, 44], "fill": [41, 44], "easiest": [41, 48, 55], "integ": [41, 44], "text2": 41, "could": [41, 42, 43, 44], "lead": [41, 44], "sql": [41, 44], "inject": [41, 44], "pars": [41, 46], "read_row": [41, 46], "place": 41, "With": 41, "immedi": 42, "continu": [42, 60], "still": [42, 43, 50, 60], "progress": 42, "interrupt": 42, "current": [42, 50, 54, 56], "turn": 42, "no_timeout_profile_handl": 42, "block": 42, "indefinit": 42, "hang": 42, "truncat": 42, "three_sec_timeout_profile_handl": 42, "last": 42, "arriv": 42, "omit": 43, "cqlsh": 43, "my_keyspac": 43, "easili": 43, "other_keyspac": 43, "other_t": 43, "use_keyspac": 43, "test1": 43, "test2": 43, "argument": 43, "whether": 43, "slightli": 43, "half": 43, "insensit": 43, "altogeth": 43, "happen": [43, 50, 61], "lowercas": 43, "uppercas": 43, "serializerow": 44, "sort": 44, "intstr": 44, "int_str": 44, "42_i32": 44, "hello": [44, 45], "to_own": 44, "intstringcustom": 44, "first_valu": 44, "second_valu": 44, "int_string_custom": 44, "trail": 44, "coma": 44, "syntax": 44, "val": 44, "cqlvalu": 44, "avalu": 44, "bvalu": 44, "null_i32": 44, "tombston": 44, "maybeunset": 44, "suboptim": 44, "enum": 44, "unset_i32": 44, "sure": [44, 50], "instruct": 44, "myproject": 45, "36": 45, "14": 45, "r": 45, "readi": [46, 48], "small": 46, "extab": 46, "topic": 47, "docker": 47, "imag": 48, "linux": 48, "sudo": 48, "rm": 48, "p": 48, "smp": 48, "download": 48, "minut": 48, "listen": 48, "172": 48, "stop": 48, "press": 48, "ctrl": 48, "found": 48, "dockerhub": 48, "high": [49, 52], "chanc": [49, 50, 52], "datastax": [49, 50], "java": [49, 50], "defaultretrypolici": [49, 50], "set_retry_polici": 49, "lower": [50, 52], "bewar": 50, "break": 50, "guarante": 50, "word": 50, "quorum": 50, "preced": 50, "understood": 50, "highli": 50, "But": 50, "top": 50, "respond": [50, 60], "greater": 50, "writetyp": 50, "unloggedbatch": 50, "acknowledg": 50, "furthermor": 50, "ignor": 50, "except": 50, "rule": 50, "eachquorum": 50, "reach": 50, "overal": 50, "assumpt": 50, "host": [50, 54], "coordin": 50, "know": 50, "thu": 50, "silent": 50, "persist": 50, "idea": 50, "thing": 50, "someth": 50, "risk": 50, "stale": 50, "downgrading_consistency_retry_polici": 50, "downgradingconsistencyretrypolici": 50, "falthroughretrypolici": 51, "straight": [51, 52], "decid": [52, 60], "fallthrough": 52, "downgrad": 52, "behav": 52, "retrypolici": 52, "retrysess": 52, "increas": 52, "danger": 52, "figur": 52, "set_is_idempot": 52, "present": 53, "demand": 53, "newest": 53, "refresh_metadata": 53, "metadata": 53, "snapshot": 53, "examin": 53, "obtain": [53, 61], "belong": 53, "materi": 53, "strategi": [53, 56], "definit": 53, "partition": 53, "show": 53, "cluster_data": 53, "get_cluster_data": 53, "get_keyspace_info": 53, "keyspace_nam": 53, "keyspace_info": 53, "ttabl": 53, "tview": 53, "tudt": 53, "user_defined_typ": 53, "trigger": 54, "percentilespeculativeexecutionpolici": 54, "execution_profil": [54, 55], "delai": 55, "count": 55, "techniqu": 56, "pre": 56, "emptiv": 56, "repli": 56, "tracing_id": [57, 58, 59, 61], "tracinginfo": [57, 58, 59, 61], "set_trac": [57, 58, 59], "re": 57, "system_trac": [57, 58, 59, 61], "tracing_info": [57, 58, 59], "get_tracing_info": [57, 58, 59, 61], "subsequ": 58, "rowiter": 58, "row_iter": 58, "_row": 58, "get_tracing_id": 58, "prepare_tracing_id": 59, "to_prepar": 59, "fiber": 60, "historycollector": 60, "history_listen": 60, "set_history_listen": 60, "save": 60, "_ignore_error": 60, "structured_histori": 60, "clone_structured_histori": 60, "didn": 60, "encount": 60, "difficulti": 60, "start_tim": 60, "2022": 60, "25": 60, "21": 60, "50": 60, "445075147": 60, "445151628": 60, "447444362": 60, "447447970": 60, "had": 60, "troubl": 60, "26": 60, "15": 60, "28": 60, "525367409": 60, "219": 60, "525409294": 60, "yet": 60, "537074167": 60, "217": 60, "537126083": 60, "548050242": 60, "218": 60, "548089083": 60, "590052778": 60, "590078119": 60, "understand": 60, "answer": 60, "consult": 60, "made": [60, 61], "tri": 60, "quicker": 60, "spawn": 60, "wasn": 60, "acquir": 60, "analyz": 60, "structur": 60, "monitor": 61, "signifi": 61, "went": 61, "go": 61, "insid": 61, "think": 61}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"authent": 0, "import": 0, "The": 0, "default": [0, 32, 49], "credenti": 0, "ar": 0, "sent": 0, "plain": 0, "text": [0, 14], "server": 0, "For": 0, "thi": 0, "reason": 0, "i": [0, 32, 40], "highli": 0, "recommend": 0, "us": [0, 2, 3, 39, 43, 48], "conjunct": 0, "client": 0, "node": [0, 28], "encrypt": 0, "ssl": 0, "trust": 0, "network": 0, "environ": 0, "custom": [0, 32, 39, 60], "compress": 1, "connect": [2, 46], "cluster": 2, "best": 2, "practic": 2, "session": [2, 37, 58, 59], "metadata": 2, "scylla": [2, 27, 48], "cloud": 2, "serverless": 2, "tl": 3, "enabl": 3, "featur": 3, "blob": 5, "list": [6, 32], "set": [6, 22, 25], "map": 6, "counter": 7, "data": [8, 39, 44], "type": [8, 19, 39, 44], "date": 9, "cqldate": 9, "chrono": [9, 15, 16], "naived": 9, "time": [9, 15, 16], "decim": 10, "valu": [10, 21, 32, 34, 39, 41, 44], "cqldecim": 10, "bigdecim": 10, "durat": 11, "inet": 12, "bool": 13, "tinyint": 13, "smallint": 13, "int": 13, "bigint": [13, 21], "float": 13, "doubl": 13, "ascii": 14, "varchar": 14, "cqltime": 15, "naivetim": 15, "timestamp": 16, "cqltimestamp": 16, "datetim": 16, "offsetdatetim": 16, "timeuuid": 17, "tupl": 18, "user": 19, "defin": 19, "uuid": 20, "varint": 21, "num_bigint": 21, "cqlvarint": 21, "exampl": [21, 22, 24, 25, 26, 31, 36, 49, 50, 51, 54, 55, 60], "creat": [22, 28, 45], "profil": [22, 23, 24, 26], "execut": [23, 25, 26, 37, 54, 55, 56, 60, 61], "all": 24, "option": [24, 34, 37], "support": 24, "prioriti": 25, "remap": 26, "handl": 26, "rust": 27, "driver": [27, 31, 60], "other": [27, 39, 44], "document": 27, "content": 27, "defaultpolici": 28, "semant": 28, "prefer": 28, "datacent": 28, "failov": 28, "token": 28, "awar": 28, "latenc": 28, "order": 28, "produc": 28, "plan": [28, 29], "load": 29, "balanc": 29, "introduct": 29, "polici": [29, 49, 50, 51, 52], "configur": [29, 36, 52], "loadbalancingpolici": 29, "trait": [29, 32, 60], "pick": 29, "fallback": 29, "on_query_success": 29, "on_query_failur": 29, "log": 30, "metric": 31, "collect": [31, 60], "adjust": 32, "code": [32, 60], "chang": 32, "serial": 32, "api": 32, "introduc": 32, "0": 32, "11": 32, "background": 32, "old": 32, "v": 32, "new": 32, "migrat": [32, 33], "scenario": 32, "differ": 32, "behavior": 32, "serializerow": 32, "serializecql": 32, "macro": 32, "prepar": [32, 34, 37, 57, 59], "mandatori": 32, "non": 32, "empti": 32, "from": 32, "gradual": 32, "convert": 32, "an": 32, "object": 32, "implement": 32, "guid": 33, "batch": [34, 57], "statement": 34, "perform": [34, 36, 37, 41], "lightweight": 35, "transact": 35, "lwt": 35, "queri": [35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 52, 57, 58, 60, 61], "format": 35, "page": [36, 58], "size": 36, "pass": 36, "state": 36, "manual": [36, 40], "make": 38, "result": [39, 41], "basic": 39, "represent": 39, "pars": 39, "into_typ": 39, "conveni": 39, "method": 39, "null": [39, 44], "row": 39, "struct": 39, "schema": [40, 53], "agreement": 40, "autom": 40, "await": 40, "interv": 40, "check": 40, "now": 40, "simpl": [41, 46, 55, 57], "first": 41, "argument": 41, "second": 41, "timeout": 42, "keyspac": 43, "multipl": 43, "onc": 43, "case": 43, "sensit": 43, "unset": 44, "project": 45, "run": [46, 48], "quick": 47, "start": 47, "docker": 48, "more": 48, "inform": 48, "retri": [49, 50, 51, 52], "downgrad": 50, "consist": 50, "fallthrough": 51, "idempot": 52, "fetch": 53, "inspect": 53, "percentil": 54, "specul": [54, 55, 56, 60], "trace": [57, 58, 59, 61], "query_it": 58, "execute_it": 58, "histori": [60, 61], "output": 60, "how": 60, "No": 60, "structuredhistori": 60, "historylisten": 60}, "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": {"Connecting to the cluster": [[2, "connecting-to-the-cluster"]], "Best practices for using Session": [[2, "best-practices-for-using-session"]], "Metadata": [[2, "metadata"]], "Scylla Cloud Serverless": [[2, "scylla-cloud-serverless"]], "List, Set, Map": [[6, "list-set-map"]], "List": [[6, "list"]], "Set": [[6, "set"]], "Map": [[6, "map"]], "Decimal": [[10, "decimal"]], "value::CqlDecimal": [[10, "value-cqldecimal"]], "bigdecimal::BigDecimal": [[10, "bigdecimal-bigdecimal"]], "Authentication": [[0, "authentication"]], "Important: The default authentication credentials are sent in plain text to the server. For this reason, it is highly recommended that this be used in conjunction with client-to-node encryption (SSL), or in a trusted network environment.": [[0, "important-the-default-authentication-credentials-are-sent-in-plain-text-to-the-server-for-this-reason-it-is-highly-recommended-that-this-be-used-in-conjunction-with-client-to-node-encryption-ssl-or-in-a-trusted-network-environment"]], "Custom Authentication": [[0, "custom-authentication"]], "Counter": [[7, "counter"]], "Data Types": [[8, "data-types"]], "Duration": [[11, "duration"]], "Date": [[9, "date"]], "CqlDate": [[9, "cqldate"]], "chrono::NaiveDate": [[9, "chrono-naivedate"]], "time::Date": [[9, "time-date"]], "TLS": [[3, "tls"]], "Enabling feature": [[3, "enabling-feature"]], "Using TLS": [[3, "using-tls"]], "Blob": [[5, "blob"]], "Compression": [[1, "compression"]], "Timestamp": [[16, "timestamp"]], "CqlTimestamp": [[16, "cqltimestamp"]], "chrono::DateTime": [[16, "chrono-datetime"]], "time::OffsetDateTime": [[16, "time-offsetdatetime"]], "Ascii, Text, Varchar": [[14, "ascii-text-varchar"]], "Timeuuid": [[17, "timeuuid"]], "Inet": [[12, "inet"]], "Varint": [[21, "varint"]], "num_bigint::BigInt": [[21, "num-bigint-bigint"]], "value::CqlVarint": [[21, "value-cqlvarint"]], "Example": [[21, "example"], [22, "example"], [22, "id1"], [22, "id2"], [26, "example"], [31, "example"], [25, "example"], [24, "example"], [55, "example"], [54, "example"]], "Execution profiles": [[23, "execution-profiles"]], "Uuid": [[20, "uuid"]], "Tuple": [[18, "tuple"]], "Bool, Tinyint, Smallint, Int, Bigint, Float, Double": [[13, "bool-tinyint-smallint-int-bigint-float-double"]], "Bool": [[13, "bool"]], "Tinyint": [[13, "tinyint"]], "Smallint": [[13, "smallint"]], "Int": [[13, "int"]], "Bigint": [[13, "bigint"]], "Float": [[13, "float"]], "Double": [[13, "double"]], "User defined types": [[19, "user-defined-types"]], "Creating a profile and setting it": [[22, "creating-a-profile-and-setting-it"]], "Time": [[15, "time"]], "CqlTime": [[15, "cqltime"]], "chrono::NaiveTime": [[15, "chrono-naivetime"]], "time::Time": [[15, "time-time"]], "USE keyspace": [[43, "use-keyspace"]], "Multiple use queries at once": [[43, "multiple-use-queries-at-once"]], "Case sensitivity": [[43, "case-sensitivity"]], "Query values": [[44, "query-values"]], "NULL values": [[44, "null-values"], [39, "null-values"]], "Unset values": [[44, "unset-values"]], "Other data types": [[44, "other-data-types"], [39, "other-data-types"]], "Making queries": [[38, "making-queries"]], "Simple query": [[41, "simple-query"]], "First argument - the query": [[41, "first-argument-the-query"]], "Second argument - the values": [[41, "second-argument-the-values"]], "Query result": [[41, "query-result"], [39, "query-result"]], "Performance": [[41, "performance"], [37, "performance"], [36, "performance"], [34, "performance"]], "Connecting and running a simple query": [[46, "connecting-and-running-a-simple-query"]], "Creating a project": [[45, "creating-a-project"]], "Quick Start": [[47, "quick-start"]], "Query timeouts": [[42, "query-timeouts"]], "Prepared query": [[37, "prepared-query"]], "Session::prepare": [[37, "session-prepare"]], "Session::execute": [[37, "session-execute"]], "Query options": [[37, "query-options"]], "Schema agreement": [[40, "schema-agreement"]], "Automated awaiting schema agreement": [[40, "automated-awaiting-schema-agreement"]], "Manually awaiting schema agreement": [[40, "manually-awaiting-schema-agreement"]], "Interval of checking for schema agreement": [[40, "interval-of-checking-for-schema-agreement"]], "Checking if schema is in agreement now": [[40, "checking-if-schema-is-in-agreement-now"]], "Paged query": [[36, "paged-query"]], "Examples": [[36, "examples"], [49, "examples"], [51, "examples"], [50, "examples"]], "Configuring page size": [[36, "configuring-page-size"]], "Passing the paging state manually": [[36, "passing-the-paging-state-manually"]], "Basic representation": [[39, "basic-representation"]], "Parsing using into_typed": [[39, "parsing-using-into-typed"]], "Parsing using convenience methods": [[39, "parsing-using-convenience-methods"]], "Parsing row as a custom struct": [[39, "parsing-row-as-a-custom-struct"]], "Logging": [[30, "logging"]], "Scylla Rust Driver": [[27, "scylla-rust-driver"]], "Other documentation": [[27, "other-documentation"]], "Contents": [[27, "contents"]], "Remapping execution profile handles": [[26, "remapping-execution-profile-handles"]], "Load balancing": [[29, "load-balancing"]], "Introduction": [[29, "introduction"]], "Plan": [[29, "plan"]], "Policy": [[29, "policy"]], "Configuration": [[29, "configuration"]], "LoadBalancingPolicy trait": [[29, "loadbalancingpolicy-trait"]], "pick and fallback:": [[29, "pick-and-fallback"]], "on_query_success and on_query_failure:": [[29, "on-query-success-and-on-query-failure"]], "Migration guides": [[33, "migration-guides"]], "Lightweight transaction (LWT) query": [[35, "lightweight-transaction-lwt-query"]], "Format of the query": [[35, "format-of-the-query"]], "Batch statement": [[34, "batch-statement"]], "Preparing a batch": [[34, "preparing-a-batch"]], "Batch options": [[34, "batch-options"]], "Batch values": [[34, "batch-values"]], "Driver metrics": [[31, "driver-metrics"]], "Collected metrics:": [[31, "collected-metrics"]], "Adjusting code to changes in serialization API introduced in 0.11": [[32, "adjusting-code-to-changes-in-serialization-api-introduced-in-0-11"]], "Background": [[32, "background"]], "Old vs. new": [[32, "old-vs-new"]], "Migration scenarios": [[32, "migration-scenarios"]], "Different default behavior in SerializeRow/SerializeCql macros": [[32, "different-default-behavior-in-serializerow-serializecql-macros"]], "Preparing is mandatory with a non-empty list of values": [[32, "preparing-is-mandatory-with-a-non-empty-list-of-values"]], "Migrating from old to new traits gradually": [[32, "migrating-from-old-to-new-traits-gradually"]], "Converting an object implementing an old trait to a new trait": [[32, "converting-an-object-implementing-an-old-trait-to-a-new-trait"]], "Custom implementations of old traits": [[32, "custom-implementations-of-old-traits"]], "Priorities of execution settings": [[25, "priorities-of-execution-settings"]], "DefaultPolicy": [[28, "defaultpolicy"]], "Creating a DefaultPolicy": [[28, "creating-a-defaultpolicy"]], "Semantics of DefaultPolicy": [[28, "semantics-of-defaultpolicy"]], "Preferences": [[28, "preferences"]], "Datacenter Failover": [[28, "datacenter-failover"]], "Token awareness": [[28, "token-awareness"]], "Latency awareness": [[28, "latency-awareness"]], "Creating a latency aware DefaultPolicy": [[28, "creating-a-latency-aware-defaultpolicy"]], "Node order in produced plans": [[28, "node-order-in-produced-plans"]], "All options supported by a profile": [[24, "all-options-supported-by-a-profile"]], "Query Execution History": [[60, "query-execution-history"], [61, "query-execution-history"]], "Example code": [[60, "example-code"]], "Output": [[60, "output"]], "How the driver executes queries": [[60, "how-the-driver-executes-queries"]], "No speculative execution": [[60, "no-speculative-execution"]], "Speculative execution": [[60, "speculative-execution"], [56, "speculative-execution"]], "StructuredHistory": [[60, "structuredhistory"]], "HistoryListener trait, custom history collecting": [[60, "historylistener-trait-custom-history-collecting"]], "Query tracing": [[61, "query-tracing"]], "Tracing": [[61, "tracing"]], "Default retry policy": [[49, "default-retry-policy"]], "Tracing Session::prepare": [[59, "tracing-session-prepare"]], "Simple speculative execution": [[55, "simple-speculative-execution"]], "Tracing a paged query": [[58, "tracing-a-paged-query"]], "Tracing Session::query_iter": [[58, "tracing-session-query-iter"]], "Tracing Session::execute_iter": [[58, "tracing-session-execute-iter"]], "Tracing a simple/prepared/batch query": [[57, "tracing-a-simple-prepared-batch-query"]], "Tracing a simple query": [[57, "tracing-a-simple-query"]], "Tracing a prepared query": [[57, "tracing-a-prepared-query"]], "Tracing a batch query": [[57, "tracing-a-batch-query"]], "Fallthrough retry policy": [[51, "fallthrough-retry-policy"]], "Downgrading consistency retry policy": [[50, "downgrading-consistency-retry-policy"]], "Schema": [[53, "schema"]], "Fetching schema": [[53, "fetching-schema"]], "Inspecting schema": [[53, "inspecting-schema"]], "Percentile speculative execution": [[54, "percentile-speculative-execution"]], "Retry policy configuration": [[52, "retry-policy-configuration"]], "Retry policies": [[52, "retry-policies"]], "Query idempotence": [[52, "query-idempotence"]], "Running Scylla using Docker": [[48, "running-scylla-using-docker"]], "Running scylla": [[48, "running-scylla"]], "More information": [[48, "more-information"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/v0.12.0/sitemap.xml b/v0.12.0/sitemap.xml new file mode 100644 index 0000000000..45ac22cc15 --- /dev/null +++ b/v0.12.0/sitemap.xml @@ -0,0 +1,2 @@ + +https://rust-driver.docs.scylladb.com/stable/connecting/authentication.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/compression.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/connecting.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/tls.htmlhttps://rust-driver.docs.scylladb.com/stable/contents.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/time.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/blob.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/collections.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/timestamp.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/counter.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/timeuuid.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/tuple.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/data-types.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/date.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/decimal.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/udt.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/duration.htmlhttps://rust-driver.docs.scylladb.com/stable/load-balancing/load-balancing.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/uuid.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/inet.htmlhttps://rust-driver.docs.scylladb.com/stable/logging/logging.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/primitive.htmlhttps://rust-driver.docs.scylladb.com/stable/metrics/metrics.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/text.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/varint.htmlhttps://rust-driver.docs.scylladb.com/stable/migration-guides/0.11-serialization.htmlhttps://rust-driver.docs.scylladb.com/stable/migration-guides/migration-guides.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/create-and-use.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/basic.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/execution-profiles.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/paged.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/prepare.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/maximal-example.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/query-history.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/batch.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/priority.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/lwt.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/remap.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/tracing.htmlhttps://rust-driver.docs.scylladb.com/stable/index.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/paged.htmlhttps://rust-driver.docs.scylladb.com/stable/load-balancing/default-policy.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/usekeyspace.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/prepared.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/values.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/queries.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/create-project.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/result.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/schema-agreement.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/simple.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/example.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/timeouts.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/quickstart.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/scylla-docker.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/default.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/downgrading-consistency.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/fallthrough.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/retry-policy.htmlhttps://rust-driver.docs.scylladb.com/stable/schema/schema.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/percentile.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/simple.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/speculative.htmlhttps://rust-driver.docs.scylladb.com/stable/genindex.htmlhttps://rust-driver.docs.scylladb.com/stable/404.htmlhttps://rust-driver.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/v0.12.0/speculative-execution/percentile.html b/v0.12.0/speculative-execution/percentile.html new file mode 100644 index 0000000000..fbb65595f3 --- /dev/null +++ b/v0.12.0/speculative-execution/percentile.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Percentile speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Percentile speculative execution

          +

          This policy has access to Metrics shared with session, and triggers +speculative execution when the request to the current host is above a +given percentile.

          +
          +

          Example

          +

          To use this policy in Session:

          +
          use std::{sync::Arc, time::Duration};
          +use scylla::{
          +    Session,
          +    SessionBuilder,
          +    speculative_execution::PercentileSpeculativeExecutionPolicy,
          +    transport::execution_profile::ExecutionProfile,
          +};
          +
          +let policy = PercentileSpeculativeExecutionPolicy  {
          +    max_retry_count: 3,
          +    percentile: 99.0,
          +};
          +
          +let handle = ExecutionProfile::builder()
          +    .speculative_execution_policy(Some(Arc::new(policy)))
          +    .build()
          +    .into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .default_execution_profile_handle(handle)
          +    .build()
          +    .await?;
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/speculative-execution/simple.html b/v0.12.0/speculative-execution/simple.html new file mode 100644 index 0000000000..2891bcab7c --- /dev/null +++ b/v0.12.0/speculative-execution/simple.html @@ -0,0 +1,664 @@ + + + + + + + + + + + + + Simple speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Simple speculative execution

          +

          The easiest speculative execution policy available. It starts another +execution of a query after constant delay of retry_interval and does at most +max_retry_count speculative query executions (not counting the first, +non-speculative one).

          +
          +

          Example

          +

          To use this policy in Session:

          +
          use std::{sync::Arc, time::Duration};
          +use scylla::{
          +    Session,
          +    SessionBuilder,
          +    speculative_execution::SimpleSpeculativeExecutionPolicy,
          +    transport::execution_profile::ExecutionProfile,
          +};
          +
          +let policy = SimpleSpeculativeExecutionPolicy {
          +    max_retry_count: 3,
          +    retry_interval: Duration::from_millis(100),
          +};
          +
          +let handle = ExecutionProfile::builder()
          +    .speculative_execution_policy(Some(Arc::new(policy)))
          +    .build()
          +    .into_handle();
          +
          +let session: Session = SessionBuilder::new()
          +    .known_node("127.0.0.1:9042")
          +    .default_execution_profile_handle(handle)
          +    .build()
          +    .await?;
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/speculative-execution/speculative.html b/v0.12.0/speculative-execution/speculative.html new file mode 100644 index 0000000000..b71798ce7d --- /dev/null +++ b/v0.12.0/speculative-execution/speculative.html @@ -0,0 +1,629 @@ + + + + + + + + + + + + + Speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Speculative execution

          +

          Speculative query execution is an optimization technique where a driver +pre-emptively starts a second execution of a query against another node, +before the first node has replied.

          +

          There are multiple speculative execution strategies that the driver can use. +Speculative execution can be configured for the whole whole Session during +its creation.

          +

          Available speculative execution strategies:

          + +

          Speculative execution is not enabled by default, and currently only +non-iter session methods use it.

          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/tracing/basic.html b/v0.12.0/tracing/basic.html new file mode 100644 index 0000000000..4a8814fd69 --- /dev/null +++ b/v0.12.0/tracing/basic.html @@ -0,0 +1,708 @@ + + + + + + + + + + + + + Tracing a simple/prepared/batch query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Tracing a simple/prepared/batch query

          +

          Simple query, prepared query and batch query +return a QueryResult which contains a tracing_id if tracing was enabled.

          +
          +

          Tracing a simple query

          +
          use scylla::query::Query;
          +use scylla::QueryResult;
          +use scylla::tracing::TracingInfo;
          +use uuid::Uuid;
          +
          +// Create a Query manually and enable tracing
          +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)");
          +query.set_tracing(true);
          +
          +let res: QueryResult = session.query(query, &[]).await?;
          +let tracing_id: Option<Uuid> = res.tracing_id;
          +
          +if let Some(id) = tracing_id {
          +    // Query tracing info from system_traces.sessions and system_traces.events
          +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
          +    println!("tracing_info: {:#?}", tracing_info);
          +}
          +
          +
          +
          +
          +

          Tracing a prepared query

          +
          use scylla::prepared_statement::PreparedStatement;
          +use scylla::QueryResult;
          +use scylla::tracing::TracingInfo;
          +use uuid::Uuid;
          +
          +// Prepare the query
          +let mut prepared: PreparedStatement = session
          +    .prepare("SELECT a FROM ks.tab")
          +    .await?;
          +
          +// Enable tracing for the prepared query
          +prepared.set_tracing(true);
          +
          +let res: QueryResult = session.execute(&prepared, &[]).await?;
          +let tracing_id: Option<Uuid> = res.tracing_id;
          +
          +if let Some(id) = tracing_id {
          +    // Query tracing info from system_traces.sessions and system_traces.events
          +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
          +    println!("tracing_info: {:#?}", tracing_info);
          +}
          +
          +
          +
          +
          +

          Tracing a batch query

          +
          use scylla::batch::Batch;
          +use scylla::QueryResult;
          +use scylla::tracing::TracingInfo;
          +use uuid::Uuid;
          +
          +// Create a batch statement
          +let mut batch: Batch = Default::default();
          +batch.append_statement("INSERT INTO ks.tab (a) VALUES(4)");
          +
          +// Enable tracing
          +batch.set_tracing(true);
          +
          +let res: QueryResult = session.batch(&batch, ((),)).await?;
          +let tracing_id: Option<Uuid> = res.tracing_id;
          +
          +if let Some(id) = tracing_id {
          +    // Query tracing info from system_traces.sessions and system_traces.events
          +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
          +    println!("tracing_info: {:#?}", tracing_info);
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/tracing/paged.html b/v0.12.0/tracing/paged.html new file mode 100644 index 0000000000..482d1d627e --- /dev/null +++ b/v0.12.0/tracing/paged.html @@ -0,0 +1,696 @@ + + + + + + + + + + + + + Tracing a paged query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Tracing a paged query

          +

          A paged query performs multiple simple/prepared queries to query subsequent pages.
          +If tracing is enabled the row iterator will contain a list of tracing ids for all performed queries.

          +
          +

          Tracing Session::query_iter

          +
          use scylla::query::Query;
          +use scylla::transport::iterator::RowIterator;
          +use scylla::tracing::TracingInfo;
          +use futures::StreamExt;
          +use uuid::Uuid;
          +
          +// Create a Query manually and enable tracing
          +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)");
          +query.set_tracing(true);
          +
          +// Create a paged query iterator and fetch pages
          +let mut row_iterator: RowIterator = session.query_iter(query, &[]).await?;
          +while let Some(_row) = row_iterator.next().await {
          +    // Receive rows
          +}
          +
          +// Now there are tracing ids for each performed query
          +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids();
          +
          +for id in tracing_ids {
          +    // Query tracing info from system_traces.sessions and system_traces.events
          +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
          +    println!("tracing_info: {:#?}", tracing_info);
          +}
          +
          +
          +
          +
          +

          Tracing Session::execute_iter

          +
          use scylla::prepared_statement::PreparedStatement;
          +use scylla::transport::iterator::RowIterator;
          +use scylla::tracing::TracingInfo;
          +use futures::StreamExt;
          +use uuid::Uuid;
          +
          +// Prepare the query
          +let mut prepared: PreparedStatement = session
          +    .prepare("SELECT a FROM ks.tab")
          +    .await?;
          +
          +// Enable tracing for the prepared query
          +prepared.set_tracing(true);
          +
          +// Create a paged query iterator and fetch pages
          +let mut row_iterator: RowIterator = session.execute_iter(prepared, &[]).await?;
          +while let Some(_row) = row_iterator.next().await {
          +    // Receive rows
          +}
          +
          +// Now there are tracing ids for each performed query
          +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids();
          +
          +for id in tracing_ids {
          +    // Query tracing info from system_traces.sessions and system_traces.events
          +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
          +    println!("tracing_info: {:#?}", tracing_info);
          +}
          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/tracing/prepare.html b/v0.12.0/tracing/prepare.html new file mode 100644 index 0000000000..4e672b8084 --- /dev/null +++ b/v0.12.0/tracing/prepare.html @@ -0,0 +1,644 @@ + + + + + + + + + + + + + Tracing Session::prepare | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Tracing Session::prepare

          +

          Session::prepare prepares a query on all connections. If tracing is enabled for the Query to prepare, the resulting PreparedStatement will contain prepare_tracing_ids. prepare_tracing_ids is a list of tracing ids of prepare requests on all connections.

          +
          use scylla::query::Query;
          +use scylla::prepared_statement::PreparedStatement;
          +use scylla::tracing::TracingInfo;
          +use uuid::Uuid;
          +
          +// Prepare the query with tracing enabled
          +let mut to_prepare: Query = Query::new("SELECT a FROM ks.tab");
          +to_prepare.set_tracing(true);
          +
          +let mut prepared: PreparedStatement = session
          +    .prepare(to_prepare)
          +    .await?;
          +
          +// Now there are tracing ids for each prepare request
          +let tracing_ids: &[Uuid] = &prepared.prepare_tracing_ids;
          +
          +for id in tracing_ids {
          +    // Query tracing info from system_traces.sessions and system_traces.events
          +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
          +    println!("tracing_info: {:#?}", tracing_info);
          +}
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/tracing/query-history.html b/v0.12.0/tracing/query-history.html new file mode 100644 index 0000000000..553f873195 --- /dev/null +++ b/v0.12.0/tracing/query-history.html @@ -0,0 +1,743 @@ + + + + + + + + + + + + + Query Execution History | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Query Execution History

          +

          The driver allows to collect history of query execution.
          +This history includes all requests sent, decisions to retry and speculative execution fibers started.

          +
          +

          Example code

          +
          use scylla::query::Query;
          +use scylla::history::{HistoryCollector, StructuredHistory};
          +use std::sync::Arc;
          +
          +// Create a query for which we would like to trace the history of its execution
          +let mut query: Query = Query::new("SELECT * FROM ks.t");
          +
          +// Create a history collector and pass it to the query
          +let history_listener = Arc::new(HistoryCollector::new());
          +query.set_history_listener(history_listener.clone());
          +
          +// Run the query, doesn't matter if it failed, the history will still be saved
          +let _ignore_error = session.query(query.clone(), ()).await;
          +
          +// Access the collected history and print it
          +let structured_history: StructuredHistory = history_listener.clone_structured_history();
          +println!("Query history: {}", structured_history);
          +
          +
          +

          To see more check out the example code

          +
          +
          +

          Output

          +

          Sample output for a query that didn’t encounter any difficulties:

          +
          === Query #0 ===
          +| start_time: 2022-08-25 11:21:50.445075147 UTC
          +| Non-speculative attempts:
          +| - Attempt #0 sent to 127.0.0.1:9042
          +|   request send time: 2022-08-25 11:21:50.445151628 UTC
          +|   Success at 2022-08-25 11:21:50.447444362 UTC
          +|
          +| Query successful at 2022-08-25 11:21:50.447447970 UTC
          +=================
          +
          +
          +

          Here’s output for a query that had some trouble - nodes didn’t respond and speculative execution decided to query others in parallel. +Finally the third node provided a response.

          +
          === Query #0 ===
          +| start_time: 2022-08-26 15:08:28.525367409 UTC
          +| Non-speculative attempts:
          +| - Attempt #0 sent to 127.0.0.219:9042
          +|   request send time: 2022-08-26 15:08:28.525409294 UTC
          +|   No result yet
          +|
          +|
          +| > Speculative fiber #0
          +| fiber start time: 2022-08-26 15:08:28.537074167 UTC
          +| - Attempt #0 sent to 127.0.0.217:9042
          +|   request send time: 2022-08-26 15:08:28.537126083 UTC
          +|   No result yet
          +|
          +|
          +| > Speculative fiber #1
          +| fiber start time: 2022-08-26 15:08:28.548050242 UTC
          +| - Attempt #0 sent to 127.0.0.218:9042
          +|   request send time: 2022-08-26 15:08:28.548089083 UTC
          +|   Success at 2022-08-26 15:08:28.590052778 UTC
          +|
          +| Query successful at 2022-08-26 15:08:28.590078119 UTC
          +=================
          +
          +
          +
          +
          +

          How the driver executes queries

          +

          To read the output it’s useful to understand more about how the driver executes queries.

          +
          +

          No speculative execution

          +

          Without speculative execution the driver performs many attempts sequentially until one of them succeeds. +A single attempt consists of sending a request to some node and waiting for the answer. +In case of an error the driver consults the retry policy to decide what to do next. +The decision might be to fail the query, retry on the same node, another node, change query parameters, etc. +Once the decision is made either the query fails or another attempt is started. This continues until the query ends.

          +
          +
          +

          Speculative execution

          +

          When speculative execution is enabled at first the driver doesn’t care about it - it does the attempts sequentially and tries to get an answer. +However once a specified amount of time has passed it will decide to try new attempts in parallel +hoping that another node will be able to answer quicker. +This is done by spawning a speculative fiber. Each spawned fiber performs sequential attempts just like in non-speculative execution. +Many fibers can be spawned if the answer wasn’t acquired in time.

          +
          +
          +

          StructuredHistory

          +

          StructuredHistory +is a history representation that represents the history by listing attempts for each speculative fiber.

          +
          +
          +
          +

          HistoryListener trait, custom history collecting

          +

          History can be collected by any struct implementing the +HistoryListener trait.

          +

          The implementation of HistoryListener provided by this crate is the +HistoryCollector. +HistoryCollector simply collects all events along with their timestamps.

          +

          Information collected by HistoryCollector is just a stream of events, in order to analyze it it’s possible +to convert it to a structured representation. +StructuredHistory +can be created by calling HistoryCollector::clone_structured_history().

          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.12.0/tracing/tracing.html b/v0.12.0/tracing/tracing.html new file mode 100644 index 0000000000..64fd048d76 --- /dev/null +++ b/v0.12.0/tracing/tracing.html @@ -0,0 +1,655 @@ + + + + + + + + + + + + + Query tracing | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + + +
          +
          + Menu +
          +
          +
          +
          +
          + + +
          +

          Caution

          +

          + + You're viewing documentation for a deprecated version of Scylla Rust Driver. + + Switch to the latest stable version. +

          +
          + + + +
          + +
          + +
          +

          Query tracing

          +

          The driver has utilities for monitoring the execution of queries. +There are two separate ways to get information about what happened with a query: Tracing and Query Execution History.

          +
          +

          Tracing

          +

          Tracing is a feature provided by Scylla. When sending a query we can set a flag that signifies that we would like it to be traced. +After completing the query Scylla provides a tracing_id which can be used to fetch information about it - which nodes it was sent to, what operations were performed etc.

          +

          Queries that support tracing:

          + +

          After obtaining the tracing id you can use Session::get_tracing_info() to query tracing information.
          +TracingInfo contains values that are the same in Scylla and Cassandra®, skipping any database-specific ones.
          +If TracingInfo does not contain some needed value it’s possible to query it manually from the tables +system_traces.sessions and system_traces.events

          +
          +
          +

          Query Execution History

          +

          Tracing provides information about how the query execution went on database nodes, but it doesn’t say anything about what was going on inside the driver.
          +This is what query execution history was made for.

          +

          It allows to follow what the driver was thinking - all query attempts, retry decisions, speculative executions. +More information is available in the Query Execution History chapter.

          +
          +
          +
          +
          + + +
          + + + + + + + +
          + +
          + + + + +
          + + + + + + + \ No newline at end of file diff --git a/v0.13.0/.buildinfo b/v0.13.0/.buildinfo new file mode 100644 index 0000000000..f449ca7ef5 --- /dev/null +++ b/v0.13.0/.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: e91989ea1d62495a002d253b0d12d915 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/v0.13.0/.doctrees/connecting/authentication.doctree b/v0.13.0/.doctrees/connecting/authentication.doctree new file mode 100644 index 0000000000..31e02ee7ce Binary files /dev/null and b/v0.13.0/.doctrees/connecting/authentication.doctree differ diff --git a/v0.13.0/.doctrees/connecting/compression.doctree b/v0.13.0/.doctrees/connecting/compression.doctree new file mode 100644 index 0000000000..c99257bd74 Binary files /dev/null and b/v0.13.0/.doctrees/connecting/compression.doctree differ diff --git a/v0.13.0/.doctrees/connecting/connecting.doctree b/v0.13.0/.doctrees/connecting/connecting.doctree new file mode 100644 index 0000000000..231b791b8d Binary files /dev/null and b/v0.13.0/.doctrees/connecting/connecting.doctree differ diff --git a/v0.13.0/.doctrees/connecting/tls.doctree b/v0.13.0/.doctrees/connecting/tls.doctree new file mode 100644 index 0000000000..6824afed76 Binary files /dev/null and b/v0.13.0/.doctrees/connecting/tls.doctree differ diff --git a/v0.13.0/.doctrees/contents.doctree b/v0.13.0/.doctrees/contents.doctree new file mode 100644 index 0000000000..db46b97b4c Binary files /dev/null and b/v0.13.0/.doctrees/contents.doctree differ diff --git a/v0.13.0/.doctrees/data-types/blob.doctree b/v0.13.0/.doctrees/data-types/blob.doctree new file mode 100644 index 0000000000..7d2c8f8b97 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/blob.doctree differ diff --git a/v0.13.0/.doctrees/data-types/collections.doctree b/v0.13.0/.doctrees/data-types/collections.doctree new file mode 100644 index 0000000000..89c0004ecc Binary files /dev/null and b/v0.13.0/.doctrees/data-types/collections.doctree differ diff --git a/v0.13.0/.doctrees/data-types/counter.doctree b/v0.13.0/.doctrees/data-types/counter.doctree new file mode 100644 index 0000000000..5ed5c3898b Binary files /dev/null and b/v0.13.0/.doctrees/data-types/counter.doctree differ diff --git a/v0.13.0/.doctrees/data-types/data-types.doctree b/v0.13.0/.doctrees/data-types/data-types.doctree new file mode 100644 index 0000000000..52e410f871 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/data-types.doctree differ diff --git a/v0.13.0/.doctrees/data-types/date.doctree b/v0.13.0/.doctrees/data-types/date.doctree new file mode 100644 index 0000000000..2c0d9d2d7f Binary files /dev/null and b/v0.13.0/.doctrees/data-types/date.doctree differ diff --git a/v0.13.0/.doctrees/data-types/decimal.doctree b/v0.13.0/.doctrees/data-types/decimal.doctree new file mode 100644 index 0000000000..daf508d6f5 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/decimal.doctree differ diff --git a/v0.13.0/.doctrees/data-types/duration.doctree b/v0.13.0/.doctrees/data-types/duration.doctree new file mode 100644 index 0000000000..ff95dd0f6a Binary files /dev/null and b/v0.13.0/.doctrees/data-types/duration.doctree differ diff --git a/v0.13.0/.doctrees/data-types/inet.doctree b/v0.13.0/.doctrees/data-types/inet.doctree new file mode 100644 index 0000000000..57887a3c17 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/inet.doctree differ diff --git a/v0.13.0/.doctrees/data-types/primitive.doctree b/v0.13.0/.doctrees/data-types/primitive.doctree new file mode 100644 index 0000000000..ecda93f419 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/primitive.doctree differ diff --git a/v0.13.0/.doctrees/data-types/text.doctree b/v0.13.0/.doctrees/data-types/text.doctree new file mode 100644 index 0000000000..6cd9048744 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/text.doctree differ diff --git a/v0.13.0/.doctrees/data-types/time.doctree b/v0.13.0/.doctrees/data-types/time.doctree new file mode 100644 index 0000000000..67755869c6 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/time.doctree differ diff --git a/v0.13.0/.doctrees/data-types/timestamp.doctree b/v0.13.0/.doctrees/data-types/timestamp.doctree new file mode 100644 index 0000000000..16918f1498 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/timestamp.doctree differ diff --git a/v0.13.0/.doctrees/data-types/timeuuid.doctree b/v0.13.0/.doctrees/data-types/timeuuid.doctree new file mode 100644 index 0000000000..fc32fea5fb Binary files /dev/null and b/v0.13.0/.doctrees/data-types/timeuuid.doctree differ diff --git a/v0.13.0/.doctrees/data-types/tuple.doctree b/v0.13.0/.doctrees/data-types/tuple.doctree new file mode 100644 index 0000000000..1a448c46df Binary files /dev/null and b/v0.13.0/.doctrees/data-types/tuple.doctree differ diff --git a/v0.13.0/.doctrees/data-types/udt.doctree b/v0.13.0/.doctrees/data-types/udt.doctree new file mode 100644 index 0000000000..f2122184fe Binary files /dev/null and b/v0.13.0/.doctrees/data-types/udt.doctree differ diff --git a/v0.13.0/.doctrees/data-types/uuid.doctree b/v0.13.0/.doctrees/data-types/uuid.doctree new file mode 100644 index 0000000000..79731ed417 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/uuid.doctree differ diff --git a/v0.13.0/.doctrees/data-types/varint.doctree b/v0.13.0/.doctrees/data-types/varint.doctree new file mode 100644 index 0000000000..d40f970c67 Binary files /dev/null and b/v0.13.0/.doctrees/data-types/varint.doctree differ diff --git a/v0.13.0/.doctrees/environment.pickle b/v0.13.0/.doctrees/environment.pickle new file mode 100644 index 0000000000..b997c493e7 Binary files /dev/null and b/v0.13.0/.doctrees/environment.pickle differ diff --git a/v0.13.0/.doctrees/execution-profiles/create-and-use.doctree b/v0.13.0/.doctrees/execution-profiles/create-and-use.doctree new file mode 100644 index 0000000000..8b0b664a94 Binary files /dev/null and b/v0.13.0/.doctrees/execution-profiles/create-and-use.doctree differ diff --git a/v0.13.0/.doctrees/execution-profiles/execution-profiles.doctree b/v0.13.0/.doctrees/execution-profiles/execution-profiles.doctree new file mode 100644 index 0000000000..6373fa65cc Binary files /dev/null and b/v0.13.0/.doctrees/execution-profiles/execution-profiles.doctree differ diff --git a/v0.13.0/.doctrees/execution-profiles/maximal-example.doctree b/v0.13.0/.doctrees/execution-profiles/maximal-example.doctree new file mode 100644 index 0000000000..5c73b82bb8 Binary files /dev/null and b/v0.13.0/.doctrees/execution-profiles/maximal-example.doctree differ diff --git a/v0.13.0/.doctrees/execution-profiles/priority.doctree b/v0.13.0/.doctrees/execution-profiles/priority.doctree new file mode 100644 index 0000000000..6b558975eb Binary files /dev/null and b/v0.13.0/.doctrees/execution-profiles/priority.doctree differ diff --git a/v0.13.0/.doctrees/execution-profiles/remap.doctree b/v0.13.0/.doctrees/execution-profiles/remap.doctree new file mode 100644 index 0000000000..717976068f Binary files /dev/null and b/v0.13.0/.doctrees/execution-profiles/remap.doctree differ diff --git a/v0.13.0/.doctrees/index.doctree b/v0.13.0/.doctrees/index.doctree new file mode 100644 index 0000000000..842b79f974 Binary files /dev/null and b/v0.13.0/.doctrees/index.doctree differ diff --git a/v0.13.0/.doctrees/load-balancing/default-policy.doctree b/v0.13.0/.doctrees/load-balancing/default-policy.doctree new file mode 100644 index 0000000000..37e31e5eff Binary files /dev/null and b/v0.13.0/.doctrees/load-balancing/default-policy.doctree differ diff --git a/v0.13.0/.doctrees/load-balancing/load-balancing.doctree b/v0.13.0/.doctrees/load-balancing/load-balancing.doctree new file mode 100644 index 0000000000..6068cf9c4b Binary files /dev/null and b/v0.13.0/.doctrees/load-balancing/load-balancing.doctree differ diff --git a/v0.13.0/.doctrees/logging/logging.doctree b/v0.13.0/.doctrees/logging/logging.doctree new file mode 100644 index 0000000000..d1ca2d6d64 Binary files /dev/null and b/v0.13.0/.doctrees/logging/logging.doctree differ diff --git a/v0.13.0/.doctrees/metrics/metrics.doctree b/v0.13.0/.doctrees/metrics/metrics.doctree new file mode 100644 index 0000000000..2821901fb4 Binary files /dev/null and b/v0.13.0/.doctrees/metrics/metrics.doctree differ diff --git a/v0.13.0/.doctrees/migration-guides/0.11-serialization.doctree b/v0.13.0/.doctrees/migration-guides/0.11-serialization.doctree new file mode 100644 index 0000000000..6f20674761 Binary files /dev/null and b/v0.13.0/.doctrees/migration-guides/0.11-serialization.doctree differ diff --git a/v0.13.0/.doctrees/migration-guides/migration-guides.doctree b/v0.13.0/.doctrees/migration-guides/migration-guides.doctree new file mode 100644 index 0000000000..c695a5966a Binary files /dev/null and b/v0.13.0/.doctrees/migration-guides/migration-guides.doctree differ diff --git a/v0.13.0/.doctrees/queries/batch.doctree b/v0.13.0/.doctrees/queries/batch.doctree new file mode 100644 index 0000000000..b9f0400750 Binary files /dev/null and b/v0.13.0/.doctrees/queries/batch.doctree differ diff --git a/v0.13.0/.doctrees/queries/lwt.doctree b/v0.13.0/.doctrees/queries/lwt.doctree new file mode 100644 index 0000000000..b24a1230e1 Binary files /dev/null and b/v0.13.0/.doctrees/queries/lwt.doctree differ diff --git a/v0.13.0/.doctrees/queries/paged.doctree b/v0.13.0/.doctrees/queries/paged.doctree new file mode 100644 index 0000000000..956dfc281c Binary files /dev/null and b/v0.13.0/.doctrees/queries/paged.doctree differ diff --git a/v0.13.0/.doctrees/queries/prepared.doctree b/v0.13.0/.doctrees/queries/prepared.doctree new file mode 100644 index 0000000000..8f44a3284f Binary files /dev/null and b/v0.13.0/.doctrees/queries/prepared.doctree differ diff --git a/v0.13.0/.doctrees/queries/queries.doctree b/v0.13.0/.doctrees/queries/queries.doctree new file mode 100644 index 0000000000..6856331bdf Binary files /dev/null and b/v0.13.0/.doctrees/queries/queries.doctree differ diff --git a/v0.13.0/.doctrees/queries/result.doctree b/v0.13.0/.doctrees/queries/result.doctree new file mode 100644 index 0000000000..3476670ab6 Binary files /dev/null and b/v0.13.0/.doctrees/queries/result.doctree differ diff --git a/v0.13.0/.doctrees/queries/schema-agreement.doctree b/v0.13.0/.doctrees/queries/schema-agreement.doctree new file mode 100644 index 0000000000..79e64c2ba3 Binary files /dev/null and b/v0.13.0/.doctrees/queries/schema-agreement.doctree differ diff --git a/v0.13.0/.doctrees/queries/simple.doctree b/v0.13.0/.doctrees/queries/simple.doctree new file mode 100644 index 0000000000..fe48620c93 Binary files /dev/null and b/v0.13.0/.doctrees/queries/simple.doctree differ diff --git a/v0.13.0/.doctrees/queries/timeouts.doctree b/v0.13.0/.doctrees/queries/timeouts.doctree new file mode 100644 index 0000000000..2687dcc996 Binary files /dev/null and b/v0.13.0/.doctrees/queries/timeouts.doctree differ diff --git a/v0.13.0/.doctrees/queries/usekeyspace.doctree b/v0.13.0/.doctrees/queries/usekeyspace.doctree new file mode 100644 index 0000000000..fb57149bea Binary files /dev/null and b/v0.13.0/.doctrees/queries/usekeyspace.doctree differ diff --git a/v0.13.0/.doctrees/queries/values.doctree b/v0.13.0/.doctrees/queries/values.doctree new file mode 100644 index 0000000000..72cd8d2845 Binary files /dev/null and b/v0.13.0/.doctrees/queries/values.doctree differ diff --git a/v0.13.0/.doctrees/quickstart/create-project.doctree b/v0.13.0/.doctrees/quickstart/create-project.doctree new file mode 100644 index 0000000000..daf2502510 Binary files /dev/null and b/v0.13.0/.doctrees/quickstart/create-project.doctree differ diff --git a/v0.13.0/.doctrees/quickstart/example.doctree b/v0.13.0/.doctrees/quickstart/example.doctree new file mode 100644 index 0000000000..09e61d7258 Binary files /dev/null and b/v0.13.0/.doctrees/quickstart/example.doctree differ diff --git a/v0.13.0/.doctrees/quickstart/quickstart.doctree b/v0.13.0/.doctrees/quickstart/quickstart.doctree new file mode 100644 index 0000000000..907bc8db03 Binary files /dev/null and b/v0.13.0/.doctrees/quickstart/quickstart.doctree differ diff --git a/v0.13.0/.doctrees/quickstart/scylla-docker.doctree b/v0.13.0/.doctrees/quickstart/scylla-docker.doctree new file mode 100644 index 0000000000..9b17ec8893 Binary files /dev/null and b/v0.13.0/.doctrees/quickstart/scylla-docker.doctree differ diff --git a/v0.13.0/.doctrees/retry-policy/default.doctree b/v0.13.0/.doctrees/retry-policy/default.doctree new file mode 100644 index 0000000000..a79fd4f289 Binary files /dev/null and b/v0.13.0/.doctrees/retry-policy/default.doctree differ diff --git a/v0.13.0/.doctrees/retry-policy/downgrading-consistency.doctree b/v0.13.0/.doctrees/retry-policy/downgrading-consistency.doctree new file mode 100644 index 0000000000..1d6a03e055 Binary files /dev/null and b/v0.13.0/.doctrees/retry-policy/downgrading-consistency.doctree differ diff --git a/v0.13.0/.doctrees/retry-policy/fallthrough.doctree b/v0.13.0/.doctrees/retry-policy/fallthrough.doctree new file mode 100644 index 0000000000..7ec39cf35b Binary files /dev/null and b/v0.13.0/.doctrees/retry-policy/fallthrough.doctree differ diff --git a/v0.13.0/.doctrees/retry-policy/retry-policy.doctree b/v0.13.0/.doctrees/retry-policy/retry-policy.doctree new file mode 100644 index 0000000000..2536cfd66b Binary files /dev/null and b/v0.13.0/.doctrees/retry-policy/retry-policy.doctree differ diff --git a/v0.13.0/.doctrees/schema/schema.doctree b/v0.13.0/.doctrees/schema/schema.doctree new file mode 100644 index 0000000000..c163211339 Binary files /dev/null and b/v0.13.0/.doctrees/schema/schema.doctree differ diff --git a/v0.13.0/.doctrees/speculative-execution/percentile.doctree b/v0.13.0/.doctrees/speculative-execution/percentile.doctree new file mode 100644 index 0000000000..2f57819b70 Binary files /dev/null and b/v0.13.0/.doctrees/speculative-execution/percentile.doctree differ diff --git a/v0.13.0/.doctrees/speculative-execution/simple.doctree b/v0.13.0/.doctrees/speculative-execution/simple.doctree new file mode 100644 index 0000000000..18e8a0ff50 Binary files /dev/null and b/v0.13.0/.doctrees/speculative-execution/simple.doctree differ diff --git a/v0.13.0/.doctrees/speculative-execution/speculative.doctree b/v0.13.0/.doctrees/speculative-execution/speculative.doctree new file mode 100644 index 0000000000..484654ef0c Binary files /dev/null and b/v0.13.0/.doctrees/speculative-execution/speculative.doctree differ diff --git a/v0.13.0/.doctrees/tracing/basic.doctree b/v0.13.0/.doctrees/tracing/basic.doctree new file mode 100644 index 0000000000..0116926bca Binary files /dev/null and b/v0.13.0/.doctrees/tracing/basic.doctree differ diff --git a/v0.13.0/.doctrees/tracing/paged.doctree b/v0.13.0/.doctrees/tracing/paged.doctree new file mode 100644 index 0000000000..1825299409 Binary files /dev/null and b/v0.13.0/.doctrees/tracing/paged.doctree differ diff --git a/v0.13.0/.doctrees/tracing/prepare.doctree b/v0.13.0/.doctrees/tracing/prepare.doctree new file mode 100644 index 0000000000..d6bb64eb02 Binary files /dev/null and b/v0.13.0/.doctrees/tracing/prepare.doctree differ diff --git a/v0.13.0/.doctrees/tracing/query-history.doctree b/v0.13.0/.doctrees/tracing/query-history.doctree new file mode 100644 index 0000000000..40dc88e146 Binary files /dev/null and b/v0.13.0/.doctrees/tracing/query-history.doctree differ diff --git a/v0.13.0/.doctrees/tracing/tracing.doctree b/v0.13.0/.doctrees/tracing/tracing.doctree new file mode 100644 index 0000000000..8fbfc26edd Binary files /dev/null and b/v0.13.0/.doctrees/tracing/tracing.doctree differ diff --git a/v0.13.0/.nojekyll b/v0.13.0/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/v0.13.0/404.html b/v0.13.0/404.html new file mode 100644 index 0000000000..e283e2eea9 --- /dev/null +++ b/v0.13.0/404.html @@ -0,0 +1,31 @@ + + + + + + + + + ScyllaDB + + + + + + + + + + + +
          +

          404

          +

          The ScyllaDB monster ate your page!

          +

          + Home +

          +
          + + + \ No newline at end of file diff --git a/v0.13.0/CNAME b/v0.13.0/CNAME new file mode 100644 index 0000000000..63858016cb --- /dev/null +++ b/v0.13.0/CNAME @@ -0,0 +1 @@ +rust-driver.docs.scylladb.com \ No newline at end of file diff --git a/v0.13.0/_sources/connecting/authentication.md.txt b/v0.13.0/_sources/connecting/authentication.md.txt new file mode 100644 index 0000000000..a18ace127a --- /dev/null +++ b/v0.13.0/_sources/connecting/authentication.md.txt @@ -0,0 +1,79 @@ +# Authentication + +Driver supports both authentication by username and password and custom authentication defined by a user. +###### Important: The default authentication credentials are sent in plain text to the server. For this reason, it is highly recommended that this be used in conjunction with client-to-node encryption (SSL), or in a trusted network environment. + +To use the default authentication, specify credentials using the `user` method in `SessionBuilder`: + +```rust +use scylla::{Session, SessionBuilder}; + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .user("myusername", "mypassword") + .build() + .await?; + +``` + ### Custom Authentication + +A custom authentication is defined by implementing the `AuthenticatorSession`. +An `AuthenticatorSession` instance is created per session, so it is also necessary to define a `AuthenticatorProvider` for it. +Finally, to make use of the custom authentication, use the `authenticator_provider` method in `SessionBuilder`: + +```rust +use bytes::{BufMut, BytesMut}; +use async_trait::async_trait; +use scylla::authentication::{AuthError, AuthenticatorProvider, AuthenticatorSession}; + +struct CustomAuthenticator; + +#[async_trait] +impl AuthenticatorSession for CustomAuthenticator { + // to handle an authentication challenge initiated by the server. + // The information contained in the token parameter is authentication protocol specific. + // It may be NULL or empty. + async fn evaluate_challenge( + &mut self, + _token: Option<&[u8]>, + ) -> Result>, AuthError> { + Err("Challenges are not expected".to_string()) + } + + // to handle the success phase of exchange. The token parameters contain information that may be used to finalize the request. + async fn success(&mut self, _token: Option<&[u8]>) -> Result<(), AuthError> { + Ok(()) + } +} + +struct CustomAuthenticatorProvider; + +#[async_trait] +impl AuthenticatorProvider for CustomAuthenticatorProvider { + async fn start_authentication_session( + &self, + _name: &str, + ) -> Result<(Option>, Box), AuthError> { + let mut response = BytesMut::new(); + let cred = "\0cassandra\0cassandra"; + let cred_length = 20; + + response.put_i32(cred_length); + response.put_slice(cred.as_bytes()); + + Ok((Some(response.to_vec()), Box::new(CustomAuthenticator))) + } +} + +async fn authentication_example() -> Result<(), Box> { + use scylla::{Session, SessionBuilder}; + + let _session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .authenticator_provider(Arc::new(CustomAuthenticatorProvider)) + .build() + .await?; + + Ok(()) +} +``` diff --git a/v0.13.0/_sources/connecting/compression.md.txt b/v0.13.0/_sources/connecting/compression.md.txt new file mode 100644 index 0000000000..4ba755e47c --- /dev/null +++ b/v0.13.0/_sources/connecting/compression.md.txt @@ -0,0 +1,30 @@ +# Compression + +By default the driver does not use any compression on connections.\ +It's possible to specify a preferred compression algorithm. \ +The driver will try using it, but if the database doesn't support it, it will fall back to no compression. + +Available compression algorithms: +* Snappy +* LZ4 + +An example enabling `Snappy` compression algorithm: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::Compression; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .compression(Some(Compression::Snappy)) + .build() + .await?; + + Ok(()) +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/connecting/connecting.md.txt b/v0.13.0/_sources/connecting/connecting.md.txt new file mode 100644 index 0000000000..04b64be099 --- /dev/null +++ b/v0.13.0/_sources/connecting/connecting.md.txt @@ -0,0 +1,110 @@ +# Connecting to the cluster + +Scylla is a distributed database, which means that it operates on multiple nodes running independently. +When creating a `Session` you can specify a few known nodes to which the driver will try connecting: +```rust +use scylla::{Session, SessionBuilder}; +use std::error::Error; +use std::time::Duration; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .known_node("127.0.0.72:4321") + .known_node("localhost:8000") + .connection_timeout(Duration::from_secs(3)) + .cluster_metadata_refresh_interval(Duration::from_secs(10)) + .known_node_addr(SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), + 9000, + )) + .build() + .await?; + + Ok(()) +} +``` + +After successfully connecting to some specified node the driver will fetch topology information about +other nodes in this cluster and connect to them as well. + +## Best practices for using Session + +:::{warning} +Always try to use only a single Session object per apllication because creating them is very expensive! +::: + +The driver maintains its own pool of connections to each node and each connection is capable of handling multiple requests in parallel. Driver will also route requests to nodes / shards that actually own the data (unless the load balancing policy that you use doesn't support it). + +For those reasons, we recommend using one instance of `Session` per application. + +Creating short-lived `Session`'s (e.g. `Session` per request) is strongly discouraged because it will result in great performance penalties because creating a `Session` is a costly process - it requires estabilishing a lot of TCP connections. +Creating many `Session`'s in one application (e.g. `Session` per thread / per Tokio task) is also discouraged, because it wastes resources - as mentioned before, `Session` maintains a connection pool itself and can handle parallel queries, so you would be holding a lot of connections unnecessarily. + +If you need to share `Session` with different threads / Tokio tasks etc. use `Arc` - all methods of `Session` take `&self`, so it doesn't hinder the functionality in any way. + +## Metadata + +The driver refreshes the cluster metadata periodically, which contains information about cluster topology as well as the cluster schema. By default, the driver refreshes the cluster metadata every 60 seconds. +However, you can set the `cluster_metadata_refresh_interval` to a non-negative value to periodically refresh the cluster metadata. This is useful when you do not have unexpected amount of traffic or when you have an extra traffic causing topology to change frequently. + +## Scylla Cloud Serverless + +Scylla Serverless is an elastic and dynamic deployment model. When creating a `Session` you need to +specify the secure connection bundle as follows: + +```rust +use std::path::Path; +use std::error::Error; +use scylla::CloudSessionBuilder; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let session = CloudSessionBuilder::new(Path::new("config_data.yaml")) + .unwrap() + .build() + .await + .unwrap(); + + Ok(()) +} +``` + +Note that the bundle file will be provided after the serverless cluster is created. Here is an example of a +configuration file for a serverless cluster: + +```yaml +datacenters: + datacenter1: + certificateAuthorityData: CERTIFICATE_DATA + server: 127.0.1.1:9142 + nodeDomain: cql.cluster-id.scylla.com + insecureSkipTlsVerify: false +authInfos: + default: + clientCertificateData: CERTIFICATE_DATA + clientKeyData: KEY_DATA + username: scylladb + password: scylladb +contexts: + default: + datacenterName: datacenter1 + authInfoName: default +currentContext: default +``` + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + compression + authentication + tls + +``` \ No newline at end of file diff --git a/v0.13.0/_sources/connecting/tls.md.txt b/v0.13.0/_sources/connecting/tls.md.txt new file mode 100644 index 0000000000..86f9379955 --- /dev/null +++ b/v0.13.0/_sources/connecting/tls.md.txt @@ -0,0 +1,63 @@ +# TLS + +Driver uses the [`openssl`](https://github.com/sfackler/rust-openssl) crate for TLS functionality.\ +It was chosen because [`rustls`](https://github.com/ctz/rustls) doesn't support certificates for ip addresses +(see [issue](https://github.com/briansmith/webpki/issues/54)), which is a common use case for Scylla. + + +### Enabling feature +`openssl` is not a pure Rust library so you need enable a feature and install the proper package. + +To enable the `tls` feature add in `Cargo.toml`: +```toml +scylla = { version = "0.4", features = ["ssl"] } +openssl = "0.10.32" +``` + +Then install the package with `openssl`: +* Debian/Ubuntu: + ```bash + apt install libssl-dev pkg-config + ``` +* Fedora: + ```bash + dnf install openssl-devel + ``` + +* Arch: + ```bash + pacman -S openssl pkg-config + ``` + +### Using TLS +To use tls you will have to create an openssl +[`SslContext`](https://docs.rs/openssl/0.10.33/openssl/ssl/struct.SslContext.html) +and pass it to `SessionBuilder` + +For example, if database certificate is in the file `ca.crt`: +```rust +use scylla::{Session, SessionBuilder}; +use openssl::ssl::{SslContextBuilder, SslMethod, SslVerifyMode}; +use std::path::PathBuf; + +let mut context_builder = SslContextBuilder::new(SslMethod::tls())?; +context_builder.set_ca_file("ca.crt")?; +context_builder.set_verify(SslVerifyMode::PEER); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9142") // The the port is now 9142 + .ssl_context(Some(context_builder.build())) + .build() + .await?; + +``` + +See the full [example](https://github.com/scylladb/scylla-rust-driver/blob/main/examples/tls.rs) for more details diff --git a/v0.13.0/_sources/contents.rst.txt b/v0.13.0/_sources/contents.rst.txt new file mode 100644 index 0000000000..5bc4a37c9e --- /dev/null +++ b/v0.13.0/_sources/contents.rst.txt @@ -0,0 +1,19 @@ +.. toctree:: + :hidden: + :glob: + :titlesonly: + + index + quickstart/quickstart + connecting/connecting + queries/queries + execution-profiles/execution-profiles + data-types/data-types + load-balancing/load-balancing + retry-policy/retry-policy + speculative-execution/speculative + metrics/metrics + migration-guides/migration-guides + logging/logging + tracing/tracing + schema/schema diff --git a/v0.13.0/_sources/data-types/blob.md.txt b/v0.13.0/_sources/data-types/blob.md.txt new file mode 100644 index 0000000000..fe02634c03 --- /dev/null +++ b/v0.13.0/_sources/data-types/blob.md.txt @@ -0,0 +1,21 @@ +# Blob +`Blob` is represented as `Vec` + + +```rust +use scylla::IntoTypedRows; + +// Insert some blob into the table as a Vec +// We can insert it by reference to not move the whole blob +let to_insert: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&to_insert,)) + .await?; + +// Read blobs from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Vec,)>()?; +while let Some((blob_value,)) = iter.next().transpose()? { + println!("{:?}", blob_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/collections.md.txt b/v0.13.0/_sources/data-types/collections.md.txt new file mode 100644 index 0000000000..5ef5bf9e7e --- /dev/null +++ b/v0.13.0/_sources/data-types/collections.md.txt @@ -0,0 +1,120 @@ +# List, Set, Map + +## List +`List` is represented as `Vec` + +```rust +use scylla::IntoTypedRows; + +// Insert a list of ints into the table +let my_list: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_list,)) + .await?; + +// Read a list of ints from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Vec,)>()?; +while let Some((list_value,)) = iter.next().transpose()? { + println!("{:?}", list_value); +} +``` + +## Set +`Set` is represented as `Vec`, `HashSet` or `BTreeSet`: + +```rust +use scylla::IntoTypedRows; + +// Insert a set of ints into the table +let my_set: Vec = vec![1, 2, 3, 4, 5]; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Vec,)>()?; +while let Some((list_value,)) = iter.next().transpose()? { + println!("{:?}", list_value); +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::HashSet; + +// Insert a set of ints into the table +let my_set: HashSet = vec![1, 2, 3, 4, 5].into_iter().collect(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(HashSet,)>()?; +while let Some((list_value,)) = iter.next().transpose()? { + println!("{:?}", list_value); +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::BTreeSet; + +// Insert a set of ints into the table +let my_set: BTreeSet = vec![1, 2, 3, 4, 5].into_iter().collect(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,)) + .await?; + +// Read a set of ints from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(BTreeSet,)>()?; +while let Some((list_value,)) = iter.next().transpose()? { + println!("{:?}", list_value); +} +``` + +## Map +`Map` is represented as `HashMap` or `BTreeMap` + +```rust +use scylla::IntoTypedRows; +use std::collections::HashMap; + +// Insert a map of text and int into the table +let mut my_map: HashMap = HashMap::new(); +my_map.insert("abcd".to_string(), 16); + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,)) + .await?; + +// Read a map from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(HashMap,)>()?; +while let Some((map_value,)) = iter.next().transpose()? { + println!("{:?}", map_value); +} +``` + +```rust +use scylla::IntoTypedRows; +use std::collections::BTreeMap; + +// Insert a map of text and int into the table +let mut my_map: BTreeMap = BTreeMap::new(); +my_map.insert("abcd".to_string(), 16); + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,)) + .await?; + +// Read a map from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(BTreeMap,)>()?; +while let Some((map_value,)) = iter.next().transpose()? { + println!("{:?}", map_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/counter.md.txt b/v0.13.0/_sources/data-types/counter.md.txt new file mode 100644 index 0000000000..ba32aa5eae --- /dev/null +++ b/v0.13.0/_sources/data-types/counter.md.txt @@ -0,0 +1,16 @@ +# Counter +`Counter` is represented as `struct Counter(pub i64)`\ +`Counter` can't be inserted, it can only be read or updated. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::Counter; + +// Read counter from the table +let result = session.query("SELECT c FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Counter,)>()?; +while let Some((counter_value,)) = iter.next().transpose()? { + let counter_int_value: i64 = counter_value.0; + println!("{}", counter_int_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/data-types.md.txt b/v0.13.0/_sources/data-types/data-types.md.txt new file mode 100644 index 0000000000..0d9696e765 --- /dev/null +++ b/v0.13.0/_sources/data-types/data-types.md.txt @@ -0,0 +1,60 @@ +# Data Types + +The driver maps database data types to matching Rust types +to achieve seamless sending and receiving of CQL values. + +See the following chapters for examples on how to send and receive each data type. + +See [Query values](../queries/values.md) for more information about sending values in queries.\ +See [Query result](../queries/result.md) for more information about reading values from queries + +Database types and their Rust equivalents: +* `Boolean` <----> `bool` +* `Tinyint` <----> `i8` +* `Smallint` <----> `i16` +* `Int` <----> `i32` +* `BigInt` <----> `i64` +* `Float` <----> `f32` +* `Double` <----> `f64` +* `Ascii`, `Text`, `Varchar` <----> `&str`, `String` +* `Counter` <----> `value::Counter` +* `Blob` <----> `Vec` +* `Inet` <----> `std::net::IpAddr` +* `Uuid` <----> `uuid::Uuid` +* `Timeuuid` <----> `value::CqlTimeuuid` +* `Date` <----> `value::CqlDate`, `chrono::NaiveDate`, `time::Date` +* `Time` <----> `value::CqlTime`, `chrono::NaiveTime`, `time::Time` +* `Timestamp` <----> `value::CqlTimestamp`, `chrono::DateTime`, `time::OffsetDateTime` +* `Duration` <----> `value::CqlDuration` +* `Decimal` <----> `value::CqlDecimal`, `bigdecimal::Decimal` +* `Varint` <----> `value::CqlVarint`, `num_bigint::BigInt` (v0.3 and v0.4) +* `List` <----> `Vec` +* `Set` <----> `Vec` +* `Map` <----> `std::collections::HashMap` +* `Tuple` <----> Rust tuples +* `UDT (User defined type)` <----> Custom user structs with macros + + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + primitive + text + counter + blob + inet + uuid + timeuuid + date + time + timestamp + duration + decimal + varint + collections + tuple + udt + +``` diff --git a/v0.13.0/_sources/data-types/date.md.txt b/v0.13.0/_sources/data-types/date.md.txt new file mode 100644 index 0000000000..ce179bcb5d --- /dev/null +++ b/v0.13.0/_sources/data-types/date.md.txt @@ -0,0 +1,91 @@ +# Date + +Depending on feature flags, three different types can be used to interact with date. + +Internally [date](https://docs.scylladb.com/stable/cql/types.html#dates) is represented as number of days since +-5877641-06-23 i.e. 2^31 days before unix epoch. + +## CqlDate + +Without any extra features enabled, only `frame::value::CqlDate` is available. It's an +[`u32`](https://doc.rust-lang.org/std/primitive.u32.html) wrapper and it matches the internal date representation. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlDate; +use scylla::IntoTypedRows; + +// 1970-01-08 +let to_insert = CqlDate((1 << 31) + 7); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read raw Date from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlDate,)>() { + let (date_value,): (CqlDate,) = row?; + } +} +``` + +## chrono::NaiveDate + +If full range is not required and `chrono` feature is enabled, +[`chrono::NaiveDate`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) can be used. +[`chrono::NaiveDate`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) supports dates from +-262145-01-01 to 262143-12-31. + +```rust +use chrono::NaiveDate; +use scylla::IntoTypedRows; + +// 2021-03-24 +let to_insert = NaiveDate::from_ymd_opt(2021, 3, 24).unwrap(); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read NaiveDate from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(NaiveDate,)>()?; +while let Some((date_value,)) = iter.next().transpose()? { + println!("{:?}", date_value); +} +``` + +## time::Date + +Alternatively, `time` feature can be used to enable support of +[`time::Date`](https://docs.rs/time/0.3/time/struct.Date.html). +[`time::Date`](https://docs.rs/time/0.3/time/struct.Date.html)'s value range depends on feature flags, see its +documentation to get more info. + +```rust +use scylla::IntoTypedRows; +use time::{Date, Month}; + +// 2021-03-24 +let to_insert = Date::from_calendar_date(2021, Month::March, 24).unwrap(); + +// Insert date into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read Date from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Date,)>()?; +while let Some((date_value,)) = iter.next().transpose()? { + println!("{:?}", date_value); +} +``` diff --git a/v0.13.0/_sources/data-types/decimal.md.txt b/v0.13.0/_sources/data-types/decimal.md.txt new file mode 100644 index 0000000000..fa2f0a9b81 --- /dev/null +++ b/v0.13.0/_sources/data-types/decimal.md.txt @@ -0,0 +1,49 @@ +# Decimal +`Decimal` is represented as `value::CqlDecimal` or [`bigdecimal::BigDecimal`](https://docs.rs/bigdecimal/latest/bigdecimal/struct.BigDecimal.html) + +## value::CqlDecimal + +Without any feature flags, the user can interact with `decimal` type by making use of `value::CqlDecimal` which is a very simple wrapper representing the value as signed binary number in big-endian order with a 32-bit scale. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlDecimal; +use std::str::FromStr; + +// Insert a decimal (123.456) into the table +let to_insert: CqlDecimal = + CqlDecimal::from_signed_be_bytes_and_exponent(vec![0x01, 0xE2, 0x40], 3); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a decimal from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(CqlDecimal,)>() { + let (decimal_value,): (CqlDecimal,) = row?; + } +} +``` + +## bigdecimal::BigDecimal + +To make use of `bigdecimal::Bigdecimal` type, user should enable `bigdecimal-04` crate feature. + +```rust +use scylla::IntoTypedRows; +use bigdecimal::BigDecimal; +use std::str::FromStr; + +// Insert a decimal into the table +let to_insert: BigDecimal = BigDecimal::from_str("12345.0")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a decimal from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(BigDecimal,)>()?; +while let Some((decimal_value,)) = iter.next().transpose()? { + println!("{:?}", decimal_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/duration.md.txt b/v0.13.0/_sources/data-types/duration.md.txt new file mode 100644 index 0000000000..1d52ffc2ce --- /dev/null +++ b/v0.13.0/_sources/data-types/duration.md.txt @@ -0,0 +1,20 @@ +# Duration +`Duration` is represented as [`CqlDuration`](https://docs.rs/scylla/latest/scylla/frame/value/struct.CqlDuration.html)\ + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlDuration; + +// Insert some duration into the table +let to_insert: CqlDuration = CqlDuration { months: 1, days: 2, nanoseconds: 3 }; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read duration from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(CqlDuration,)>()?; +while let Some((duration_value,)) = iter.next().transpose()? { + println!("{:?}", duration_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/inet.md.txt b/v0.13.0/_sources/data-types/inet.md.txt new file mode 100644 index 0000000000..51588b5585 --- /dev/null +++ b/v0.13.0/_sources/data-types/inet.md.txt @@ -0,0 +1,20 @@ +# Inet +`Inet` is represented as `std::net::IpAddr` + +```rust +use scylla::IntoTypedRows; +use std::net::{IpAddr, Ipv4Addr}; + +// Insert some ip address into the table +let to_insert: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read inet from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(IpAddr,)>()?; +while let Some((inet_value,)) = iter.next().transpose()? { + println!("{:?}", inet_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/primitive.md.txt b/v0.13.0/_sources/data-types/primitive.md.txt new file mode 100644 index 0000000000..57fcd7ae9c --- /dev/null +++ b/v0.13.0/_sources/data-types/primitive.md.txt @@ -0,0 +1,148 @@ +# Bool, Tinyint, Smallint, Int, Bigint, Float, Double + +### Bool + +`Bool` is represented as rust `bool` + +```rust +use scylla::IntoTypedRows; + +// Insert a bool into the table +let to_insert: bool = true; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a bool from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(bool,)>()?; +while let Some((bool_value,)) = iter.next().transpose()? { + println!("{}", bool_value); +} +``` + +### Tinyint + +`Tinyint` is represented as rust `i8` + +```rust +use scylla::IntoTypedRows; + +// Insert a tinyint into the table +let to_insert: i8 = 123; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a tinyint from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(i8,)>()?; +while let Some((tinyint_value,)) = iter.next().transpose()? { + println!("{:?}", tinyint_value); +} +``` + +### Smallint + +`Smallint` is represented as rust `i16` + +```rust +use scylla::IntoTypedRows; + +// Insert a smallint into the table +let to_insert: i16 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a smallint from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(i16,)>()?; +while let Some((smallint_value,)) = iter.next().transpose()? { + println!("{}", smallint_value); +} +``` + +### Int + +`Int` is represented as rust `i32` + +```rust +use scylla::IntoTypedRows; + +// Insert an int into the table +let to_insert: i32 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read an int from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(i32,)>()?; +while let Some((int_value,)) = iter.next().transpose()? { + println!("{}", int_value); +} +``` + +### Bigint + +`Bigint` is represented as rust `i64` + +```rust +use scylla::IntoTypedRows; + +// Insert a bigint into the table +let to_insert: i64 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a bigint from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(i64,)>()?; +while let Some((bigint_value,)) = iter.next().transpose()? { + println!("{:?}", bigint_value); +} +``` + +### Float + +`Float` is represented as rust `f32` + +```rust +use scylla::IntoTypedRows; + +// Insert a float into the table +let to_insert: f32 = 123.0; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a float from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(f32,)>()?; +while let Some((float_value,)) = iter.next().transpose()? { + println!("{:?}", float_value); +} +``` + +### Double + +`Double` is represented as rust `f64` + +```rust +use scylla::IntoTypedRows; + +// Insert a double into the table +let to_insert: f64 = 12345.0; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a double from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(f64,)>()?; +while let Some((double_value,)) = iter.next().transpose()? { + println!("{:?}", double_value); +} +``` diff --git a/v0.13.0/_sources/data-types/text.md.txt b/v0.13.0/_sources/data-types/text.md.txt new file mode 100644 index 0000000000..a33d4743ec --- /dev/null +++ b/v0.13.0/_sources/data-types/text.md.txt @@ -0,0 +1,25 @@ +# Ascii, Text, Varchar +`Ascii`, `Text` and `Varchar` are represented as `&str` and `String` + +```rust +use scylla::IntoTypedRows; + +// Insert some text into the table as a &str +let to_insert_str: &str = "abcdef"; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_str,)) + .await?; + +// Insert some text into the table as a String +let to_insert_string: String = "abcdef".to_string(); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_string,)) + .await?; + +// Read ascii/text/varchar from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(String,)>()?; +while let Some((text_value,)) = iter.next().transpose()? { + println!("{}", text_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/time.md.txt b/v0.13.0/_sources/data-types/time.md.txt new file mode 100644 index 0000000000..cd005c97a6 --- /dev/null +++ b/v0.13.0/_sources/data-types/time.md.txt @@ -0,0 +1,89 @@ +# Time + +Depending on feature flags used, three different types can be used to interact with time. + +Internally [time](https://docs.scylladb.com/stable/cql/types.html#times) is represented as number of nanoseconds since +midnight. It can't be negative or exceed `86399999999999` (23:59:59.999999999). + +## CqlTime + +Without any extra features enabled, only `frame::value::CqlTime` is available. It's an +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) wrapper and it matches the internal time representation. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlTime; +use scylla::IntoTypedRows; + +// 64 seconds since midnight +let to_insert = CqlTime(64 * 1_000_000_000); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlTime,)>() { + let (time_value,): (CqlTime,) = row?; + } +} +``` + +## chrono::NaiveTime + +If `chrono` feature is enabled, [`chrono::NaiveTime`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) +can be used to interact with the database. Although chrono can represent leap seconds, they are not supported. +Attempts to convert [`chrono::NaiveTime`](https://docs.rs/chrono/0.4/chrono/naive/struct.NaiveDate.html) with leap +second to `CqlTime` or write it to the database will return an error. + +```rust +use chrono::NaiveTime; +use scylla::IntoTypedRows; + +// 01:02:03.456,789,012 +let to_insert = NaiveTime::from_hms_nano_opt(1, 2, 3, 456_789_012); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(NaiveTime,)>()?; +while let Some((time_value,)) = iter.next().transpose()? { + println!("{:?}", time_value); +} +``` + +## time::Time + +If `time` feature is enabled, [`time::Time`](https://docs.rs/time/0.3/time/struct.Time.html) can be used to interact +with the database. + +```rust +use scylla::IntoTypedRows; +use time::Time; + +// 01:02:03.456,789,012 +let to_insert = Time::from_hms_nano(1, 2, 3, 456_789_012).unwrap(); + +// Insert time into the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read time from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Time,)>()?; +while let Some((time_value,)) = iter.next().transpose()? { + println!("{:?}", time_value); +} +``` diff --git a/v0.13.0/_sources/data-types/timestamp.md.txt b/v0.13.0/_sources/data-types/timestamp.md.txt new file mode 100644 index 0000000000..8157751552 --- /dev/null +++ b/v0.13.0/_sources/data-types/timestamp.md.txt @@ -0,0 +1,101 @@ +# Timestamp + +Depending on feature flags, three different types can be used to interact with timestamps. + +Internally [timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) is represented as +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) describing number of milliseconds since unix epoch. + +## CqlTimestamp + +Without any extra features enabled, only `frame::value::CqlTimestamp` is available. It's an +[`i64`](https://doc.rust-lang.org/std/primitive.i64.html) wrapper and it matches the internal time representation. It's +the only type that supports full range of values that database accepts. + +However, for most use cases other types are more practical. See following sections for `chrono` and `time`. + +```rust +use scylla::frame::value::CqlTimestamp; +use scylla::IntoTypedRows; + +// 64 seconds since unix epoch, 1970-01-01 00:01:04 +let to_insert = CqlTimestamp(64 * 1000); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +if let Some(rows) = session + .query("SELECT a FROM keyspace.table", &[]) + .await? + .rows +{ + for row in rows.into_typed::<(CqlTimestamp,)>() { + let (timestamp_value,): (CqlTimestamp,) = row?; + } +} +``` + +## chrono::DateTime + +If full value range is not required, `chrono` feature can be used to enable support of +[`chrono::DateTime`](https://docs.rs/chrono/0.4/chrono/struct.DateTime.html). All values are expected to be converted +to UTC timezone explicitly, as [timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) doesn't store +timezone information. Any precision finer than 1ms will be lost. + +```rust +use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc}; +use scylla::IntoTypedRows; + +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123 +let to_insert = NaiveDateTime::new( + NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(), + NaiveTime::from_hms_milli_opt(0, 1, 4, 123).unwrap(), +) +.and_utc(); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(DateTime,)>()?; +while let Some((timestamp_value,)) = iter.next().transpose()? { + println!("{:?}", timestamp_value); +} +``` + +## time::OffsetDateTime + +Alternatively, `time` feature can be used to enable support of +[`time::OffsetDateTime`](https://docs.rs/time/0.3/time/struct.OffsetDateTime.html). As +[timestamp](https://docs.scylladb.com/stable/cql/types.html#timestamps) doesn't support timezone information, time will +be corrected to UTC and timezone info will be erased on write. On read, UTC timestamp is returned. Any precision finer +than 1ms will also be lost. + +```rust +use scylla::IntoTypedRows; +use time::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time}; + +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123 +let to_insert = PrimitiveDateTime::new( + Date::from_calendar_date(1970, Month::January, 1).unwrap(), + Time::from_hms_milli(0, 1, 4, 123).unwrap(), +) +.assume_utc(); + +// Write timestamp to the table +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timestamp from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(OffsetDateTime,)>()?; +while let Some((timestamp_value,)) = iter.next().transpose()? { + println!("{:?}", timestamp_value); +} +``` diff --git a/v0.13.0/_sources/data-types/timeuuid.md.txt b/v0.13.0/_sources/data-types/timeuuid.md.txt new file mode 100644 index 0000000000..147836543f --- /dev/null +++ b/v0.13.0/_sources/data-types/timeuuid.md.txt @@ -0,0 +1,23 @@ +# Timeuuid + +`Timeuuid` is represented as `value::CqlTimeuuid`. +`value::CqlTimeuuid` is a wrapper for `uuid::Uuid` with custom ordering logic +which follows Scylla/Cassandra semantics. + +```rust +use scylla::IntoTypedRows; +use scylla::frame::value::CqlTimeuuid; + +// Insert some timeuuid into the table +let to_insert: CqlTimeuuid = CqlTimeuuid::from_str("8e14e760-7fa8-11eb-bc66-000000000001")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read timeuuid from the table +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows { + for row in rows.into_typed::<(CqlTimeuuid,)>() { + let (timeuuid_value,): (CqlTimeuuid,) = row?; + } +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/tuple.md.txt b/v0.13.0/_sources/data-types/tuple.md.txt new file mode 100644 index 0000000000..8403d6b6b8 --- /dev/null +++ b/v0.13.0/_sources/data-types/tuple.md.txt @@ -0,0 +1,22 @@ +# Tuple + +`Tuple` is represented as rust tuples of max 16 elements. + +```rust +use scylla::IntoTypedRows; + +// Insert a tuple of int and string into the table +let to_insert: (i32, String) = (1, "abc".to_string()); +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a tuple of int and string from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<((i32, String),)>()?; +while let Some((tuple_value,)) = iter.next().transpose()? { + let int_value: i32 = tuple_value.0; + let string_value: String = tuple_value.1; + println!("({}, {})", int_value, string_value); +} +``` diff --git a/v0.13.0/_sources/data-types/udt.md.txt b/v0.13.0/_sources/data-types/udt.md.txt new file mode 100644 index 0000000000..4660d7f982 --- /dev/null +++ b/v0.13.0/_sources/data-types/udt.md.txt @@ -0,0 +1,71 @@ +# User defined types +Scylla allows users to define their own data types with named fields (See [the official documentation](https://opensource.docs.scylladb.com/stable/cql/types.html#user-defined-types))\ +To use user defined types in the driver, you can create a corresponding struct in Rust, and use it to read and write UDT values. + + +For example let's say `my_type` was created using this query: +```sql +CREATE TYPE ks.my_type (int_val int, text_val text) +``` + +To use this type in the driver, create a matching struct and derive: +- `SerializeCql`: in order to be able to use this struct in query parameters. \ + This macro requires fields of UDT and struct to have matching names, but the order + of the fields is not required to be the same. \ + Note: you can use different name using `rename` attribute - see `SerializeCql` macro documentation. +- `FromUserType`: in order to be able to use this struct in query results. \ + This macro requires fields of UDT and struct to be in the same *ORDER*. \ + This mismatch between `SerializeCql` and `FromUserType` requirements is a temporary situation - in the future `FromUserType` (or the macro that replaces it) will also require matching names. + +```rust +use scylla::macros::{FromUserType, SerializeCql}; + +// Define a custom struct that matches the User Defined Type created earlier. +// Fields must be in the same order as they are in the database and also +// have the same names. +// Wrapping a field in Option will gracefully handle null field values. +#[derive(Debug, FromUserType, SerializeCql)] +struct MyType { + int_val: i32, + text_val: Option, +} +``` + +> ***Important***\ +> For deserialization, fields in the Rust struct must be defined in the same order as they are in the database. +> When receiving values, the driver will (de)serialize fields one after another, without looking at field names. + +> ***Important***\ +> For serialization, by default fields in the Rust struct must be defined with the same names as they are in the database. +> The driver will serialize the fields in the order defined by the UDT, matching Rust fields by name. +> You can change this behaviour using macro attributes, see `SerializeCql` macro documentation for more information. + +Now it can be sent and received just like any other CQL value: +```rust +use scylla::IntoTypedRows; +use scylla::macros::{FromUserType, SerializeCql}; +use scylla::cql_to_rust::FromCqlVal; + +#[derive(Debug, FromUserType, SerializeCql)] +struct MyType { + int_val: i32, + text_val: Option, +} + +// Insert my_type into the table +let to_insert = MyType { + int_val: 17, + text_val: Some("Some string".to_string()), +}; + +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read MyType from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(MyType,)>()?; +while let Some((my_type_value,)) = iter.next().transpose()? { + println!("{:?}", my_type_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/uuid.md.txt b/v0.13.0/_sources/data-types/uuid.md.txt new file mode 100644 index 0000000000..5da0606307 --- /dev/null +++ b/v0.13.0/_sources/data-types/uuid.md.txt @@ -0,0 +1,21 @@ +# Uuid + +`Uuid` is represented as `uuid::Uuid`. + +```rust +use scylla::IntoTypedRows; +use uuid::Uuid; + +// Insert some uuid into the table +let to_insert: Uuid = Uuid::parse_str("8e14e760-7fa8-11eb-bc66-000000000001")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read uuid from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(Uuid,)>()?; +while let Some((uuid_value,)) = iter.next().transpose()? { + println!("{:?}", uuid_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/data-types/varint.md.txt b/v0.13.0/_sources/data-types/varint.md.txt new file mode 100644 index 0000000000..dd71139721 --- /dev/null +++ b/v0.13.0/_sources/data-types/varint.md.txt @@ -0,0 +1,32 @@ +# Varint +`Varint` is represented as `value::CqlVarint` or [`num_bigint::BigInt`](https://docs.rs/num-bigint/0.4.0/num_bigint/struct.BigInt.html). + +## num_bigint::BigInt + +To make use of `num_bigint::BigInt` type, user should enable one of the available feature flags (`num-bigint-03` or `num-bigint-04`). They enable support for `num_bigint::BigInt` v0.3 and v0.4 accordingly. + +## value::CqlVarint + +Without any feature flags, the user can interact with `Varint` type by making use of `value::CqlVarint` which +is a very simple wrapper representing the value as signed binary number in big-endian order. + +## Example + +```rust +use scylla::IntoTypedRows; +use num_bigint::BigInt; +use std::str::FromStr; + +// Insert a varint into the table +let to_insert: BigInt = BigInt::from_str("12345")?; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; + +// Read a varint from the table +let result = session.query("SELECT a FROM keyspace.table", &[]).await?; +let mut iter = result.rows_typed::<(BigInt,)>()?; +while let Some((varint_value,)) = iter.next().transpose()? { + println!("{:?}", varint_value); +} +``` \ No newline at end of file diff --git a/v0.13.0/_sources/execution-profiles/create-and-use.md.txt b/v0.13.0/_sources/execution-profiles/create-and-use.md.txt new file mode 100644 index 0000000000..e33d5d2a26 --- /dev/null +++ b/v0.13.0/_sources/execution-profiles/create-and-use.md.txt @@ -0,0 +1,61 @@ +# Creating a profile and setting it + +### Example +To create an `ExecutionProfile` and attach it as default for `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::LocalOne) + .request_timeout(None) // no request timeout + .build(); + +let handle = profile.into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +### Example +To create an `ExecutionProfile` and attach it to a `Query`: +```rust +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::All) + .request_timeout(Some(Duration::from_secs(30))) + .build(); + +let handle = profile.into_handle(); + +let mut query1 = Query::from("SELECT * FROM ks.table"); +query1.set_execution_profile_handle(Some(handle.clone())); + +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?"); +query2.set_execution_profile_handle(Some(handle)); +``` + +### Example +To create an `ExecutionProfile` based on another profile: +```rust +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let base_profile = ExecutionProfile::builder() + .request_timeout(Some(Duration::from_secs(30))) + .build(); + +let profile = base_profile.to_builder() + .consistency(Consistency::All) + .build(); + +``` \ No newline at end of file diff --git a/v0.13.0/_sources/execution-profiles/execution-profiles.md.txt b/v0.13.0/_sources/execution-profiles/execution-profiles.md.txt new file mode 100644 index 0000000000..6f36726aff --- /dev/null +++ b/v0.13.0/_sources/execution-profiles/execution-profiles.md.txt @@ -0,0 +1,26 @@ +# Execution profiles + +Execution profiles are a way to group various query execution configuration options together. Profiles can be created to represent different workloads, which can be run conveniently on a single session. + +The settings that an execution profile encapsulates are [as follows](maximal-example.md): +* consistency +* serial consistency +* request timeout +* load balancing policy +* retry policy +* speculative execution policy + +There are two classes of objects related to execution profiles: `ExecutionProfile` and `ExecutionProfileHandle`. The former is simply an immutable set of the settings. The latter is a handle that at particular moment points to some `ExecutionProfile` (but during its lifetime, it can change the profile it points at). Handles are assigned to `Sessions` and `Statements`.\ +\ +At any moment, handles [can be remapped](remap.md) to point to another `ExecutionProfile`. This allows convenient switching between workloads for all `Sessions` and/or `Statements` that, for instance, share common characteristics. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + create-and-use + maximal-example + priority + remap +``` \ No newline at end of file diff --git a/v0.13.0/_sources/execution-profiles/maximal-example.md.txt b/v0.13.0/_sources/execution-profiles/maximal-example.md.txt new file mode 100644 index 0000000000..b784786574 --- /dev/null +++ b/v0.13.0/_sources/execution-profiles/maximal-example.md.txt @@ -0,0 +1,35 @@ +# All options supported by a profile + +### Example +`ExecutionProfile` supports all the following options: +```rust +use scylla::query::Query; +use scylla::speculative_execution::SimpleSpeculativeExecutionPolicy; +use scylla::statement::{Consistency, SerialConsistency}; +use scylla::transport::ExecutionProfile; +use scylla::transport::load_balancing::DefaultPolicy; +use scylla::transport::retry_policy::FallthroughRetryPolicy; +use std::{sync::Arc, time::Duration}; + +let profile = ExecutionProfile::builder() + .consistency(Consistency::All) + .serial_consistency(Some(SerialConsistency::Serial)) + .request_timeout(Some(Duration::from_secs(30))) + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .load_balancing_policy(Arc::new(DefaultPolicy::default())) + .speculative_execution_policy( + Some( + Arc::new( + SimpleSpeculativeExecutionPolicy { + max_retry_count: 3, + retry_interval: Duration::from_millis(100), + } + ) + ) + ) + .build(); + +let mut query = Query::from("SELECT * FROM ks.table"); +query.set_execution_profile_handle(Some(profile.into_handle())); + +``` \ No newline at end of file diff --git a/v0.13.0/_sources/execution-profiles/priority.md.txt b/v0.13.0/_sources/execution-profiles/priority.md.txt new file mode 100644 index 0000000000..246c90fa24 --- /dev/null +++ b/v0.13.0/_sources/execution-profiles/priority.md.txt @@ -0,0 +1,48 @@ +# Priorities of execution settings + +You always have a default execution profile set for the `Session`, either the default one or overridden upon `Session` creation. Moreover, you can set a profile for specific statements, in which case the statement's profile has higher priority. Some options are also available for specific statements to be set directly on them, such as request timeout and consistency. In such case, the directly set options are preferred over those specified in execution profiles. + +> **Recap**\ +> Priorities are as follows:\ +> `Session`'s default profile < Statement's profile < options set directly on a Statement + + +### Example +Priorities of execution profiles and directly set options: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let session_profile = ExecutionProfile::builder() + .consistency(Consistency::One) + .build(); + +let query_profile = ExecutionProfile::builder() + .consistency(Consistency::Two) + .build(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(session_profile.into_handle()) + .build() + .await?; + +let mut query = Query::from("SELECT * FROM ks.table"); + +// Query is not assigned any specific profile, so session's profile is applied. +// Therefore, the query will be executed with Consistency::One. +session.query(query.clone(), ()).await?; + +query.set_execution_profile_handle(Some(query_profile.into_handle())); +// Query's profile is applied. +// Therefore, the query will be executed with Consistency::Two. +session.query(query.clone(), ()).await?; + +query.set_consistency(Consistency::Three); +// An option is set directly on the query. +// Therefore, the query will be executed with Consistency::Three. +session.query(query, ()).await?; + +``` \ No newline at end of file diff --git a/v0.13.0/_sources/execution-profiles/remap.md.txt b/v0.13.0/_sources/execution-profiles/remap.md.txt new file mode 100644 index 0000000000..470ebaefe7 --- /dev/null +++ b/v0.13.0/_sources/execution-profiles/remap.md.txt @@ -0,0 +1,69 @@ +# Remapping execution profile handles + +`ExecutionProfileHandle`s can be remapped to another `ExecutionProfile`, and the change affects all sessions and statements that have been assigned that handle. This enables quick workload switches. + +Example mapping: +* session1 -> handle1 -> profile1 +* statement1 -> handle1 -> profile1 +* statement2 -> handle2 -> profile2 + +We can now remap handle2 to profile1, so that the mapping for statement2 becomes as follows: +* statement2 -> handle2 -> profile1 + +We can also change statement1's handle to handle2, and remap handle1 to profile2, yielding: +* session1 -> handle1 -> profile2 +* statement1 -> handle2 -> profile1 +* statement2 -> handle2 -> profile1 + +As you can see, profiles are a powerful and convenient way to define and modify your workloads. + +### Example +Below, the remaps described above are followed in code. +```rust +use scylla::{Session, SessionBuilder}; +use scylla::query::Query; +use scylla::statement::Consistency; +use scylla::transport::ExecutionProfile; + +let profile1 = ExecutionProfile::builder() + .consistency(Consistency::One) + .build(); + +let profile2 = ExecutionProfile::builder() + .consistency(Consistency::Two) + .build(); + +let mut handle1 = profile1.clone().into_handle(); +let mut handle2 = profile2.clone().into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle1.clone()) + .build() + .await?; + +let mut query1 = Query::from("SELECT * FROM ks.table"); +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?"); + +query1.set_execution_profile_handle(Some(handle1.clone())); +query2.set_execution_profile_handle(Some(handle2.clone())); + +// session1 -> handle1 -> profile1 +// query1 -> handle1 -> profile1 +// query2 -> handle2 -> profile2 + +// We can now remap handle2 to profile1: +handle2.map_to_another_profile(profile1); +// ...so that the mapping for query2 becomes as follows: +// query2 -> handle2 -> profile1 + +// We can also change query1's handle to handle2: +query1.set_execution_profile_handle(Some(handle2.clone())); +// ...and remap handle1 to profile2: +handle1.map_to_another_profile(profile2); +// ...yielding: +// session1 -> handle1 -> profile2 +// query1 -> handle2 -> profile1 +// query2 -> handle2 -> profile1 + +``` \ No newline at end of file diff --git a/v0.13.0/_sources/index.md.txt b/v0.13.0/_sources/index.md.txt new file mode 100644 index 0000000000..d2a6b79313 --- /dev/null +++ b/v0.13.0/_sources/index.md.txt @@ -0,0 +1,26 @@ +# Scylla Rust Driver +This book contains documentation for [scylla-rust-driver](https://github.com/scylladb/scylla-rust-driver) - a driver +for the [Scylla](https://scylladb.com) database written in Rust. +Although optimized for Scylla, the driver is also compatible with [Apache Cassandra®](https://cassandra.apache.org/). + +### Other documentation +* [Examples](https://github.com/scylladb/scylla-rust-driver/tree/main/examples) +* [Rust and Scylla lesson](https://university.scylladb.com/courses/using-scylla-drivers/lessons/rust-and-scylla-2/) on Scylla University +* [API documentation](https://docs.rs/scylla) +* [Scylla documentation](https://docs.scylladb.com) +* [Cassandra® documentation](https://cassandra.apache.org/doc/latest/) + + +## Contents +* [Quick start](quickstart/quickstart.md) - Setting up a Rust project using `scylla-rust-driver` and running a few queries +* [Migration guides](migration-guides/migration-guides.md) - How to update the code that used an older version of this driver +* [Connecting to the cluster](connecting/connecting.md) - Configuring a connection to scylla cluster +* [Making queries](queries/queries.md) - Making different types of queries (simple, prepared, batch, paged) +* [Execution profiles](execution-profiles/execution-profiles.md) - Grouping query execution configuration options together and switching them all at once +* [Data Types](data-types/data-types.md) - How to use various column data types +* [Load balancing](load-balancing/load-balancing.md) - Load balancing configuration +* [Retry policy configuration](retry-policy/retry-policy.md) - What to do when a query fails, query idempotence +* [Driver metrics](metrics/metrics.md) - Statistics about the driver - number of queries, latency etc. +* [Logging](logging/logging.md) - Viewing and integrating logs produced by the driver +* [Query tracing](tracing/tracing.md) - Tracing query execution +* [Database schema](schema/schema.md) - Fetching and inspecting database schema diff --git a/v0.13.0/_sources/load-balancing/default-policy.md.txt b/v0.13.0/_sources/load-balancing/default-policy.md.txt new file mode 100644 index 0000000000..c1ad0ee2bf --- /dev/null +++ b/v0.13.0/_sources/load-balancing/default-policy.md.txt @@ -0,0 +1,167 @@ +# DefaultPolicy + +`DefaultPolicy` is the default load balancing policy in Scylla Rust Driver. It +can be configured to be datacenter-aware and token-aware. Datacenter failover +for queries with non-local consistency mode is also supported. + +## Creating a DefaultPolicy + +`DefaultPolicy` can be created only using `DefaultPolicyBuilder`. The +`builder()` method of `DefaultPolicy` returns a new instance of +`DefaultPolicyBuilder` with the following default values: + +- `preferences`: no particular datacenter/rack preference +- `is_token_aware`: `true` +- `permit_dc_failover`: `false` +- `latency_awareness`: `None` + +You can use the builder methods to configure the desired settings and create a +`DefaultPolicy` instance: + +```rust +use scylla::load_balancing::DefaultPolicy; + +let default_policy = DefaultPolicy::builder() + .prefer_datacenter_and_rack("dc1".to_string(), "rack1".to_string()) + .token_aware(true) + .permit_dc_failover(true) + .build(); +``` + +### Semantics of `DefaultPolicy` + +#### Preferences + +The `preferences` field in `DefaultPolicy` allows the load balancing +policy to prioritize nodes based on their location. It has three modes: + +- no preference +- preferred datacenter +- preferred datacenter and rack + +When a datacenter `"my_dc"` is preferred, the policy will treat nodes in `"my_dc"` +as "local" nodes, and nodes in other datacenters as "remote" nodes. This affects +the order in which nodes are returned by the policy when selecting nodes for +read or write operations. If no datacenter is preferred, the policy will treat +all nodes as local nodes. + +`preferences` allow the load balancing policy to prioritize nodes based on their +availability zones (racks) in the preferred datacenter, too. When a datacenter +and a rack are preferred, the policy will first return replicas in the local rack +in the preferred datacenter, and then the other replicas in the datacenter +(followed by remote replicas). After replicas, the other node will be ordered +similarly, too (local rack nodes, local datacenter nodes, remote nodes). + +When datacenter failover is disabled (`permit_dc_failover` is set to +false), the default policy will only include local nodes in load balancing +plans. Remote nodes will be excluded, even if they are alive and available to +serve requests. + +#### Datacenter Failover + +In the event of a datacenter outage or network failure, the nodes in that +datacenter may become unavailable, and clients may no longer be able to access +the data stored on those nodes. To address this, the `DefaultPolicy` supports +datacenter failover, which allows to route requests to nodes in other datacenters +if the local nodes are unavailable. + +Datacenter failover can be enabled in `DefaultPolicy` by `permit_dc_failover` +setting in the builder. When this flag is set, the policy will prefer to return +alive remote replicas if datacenter failover is permitted and possible due to +consistency constraints. + +#### Token awareness + +Token awareness refers to a mechanism by which the driver is aware of the token +range assigned to each node in the cluster. Tokens are assigned to nodes to +partition the data and distribute it across the cluster. + +When a user wants to read or write data, the driver can use token awareness to +route the request to the correct node based on the token range of the data +being accessed. This can help to minimize network traffic and improve +performance by ensuring that the data is accessed locally as much as possible. + +In the case of `DefaultPolicy`, token awareness is enabled by default, meaning +that the policy will prefer to return alive local replicas if the token is +available. This means that if the client is requesting data that falls within +the token range of a particular node, the policy will try to route the request +to that node first, assuming it is alive and responsive. + +Token awareness can significantly improve the performance and scalability of +applications built on Scylla. By using token awareness, users can ensure that +data is accessed locally as much as possible, reducing network overhead and +improving throughput. + +Please note that for token awareness to be applied, a statement must be +prepared before being executed. + +### Latency awareness + +Latency awareness is a mechanism that penalises nodes whose measured recent +average latency classifies it as falling behind the others. + +Every `update_rate` the global minimum average latency is computed, +and all nodes whose average latency is worse than `exclusion_threshold` +times the global minimum average latency become penalised for +`retry_period`. Penalisation involves putting those nodes at the very end +of the query plan. As it is often not truly beneficial to prefer +faster non-replica than replicas lagging behind the non-replicas, +this mechanism may as well worsen latencies and/or throughput. + +> **Warning** +> +> Using latency awareness is **NOT** recommended, unless prior +>benchmarks prove its beneficial impact on the specific workload's +>performance. Use with caution. + +### Creating a latency aware DefaultPolicy + +```rust +use scylla::load_balancing::{ + LatencyAwarenessBuilder, DefaultPolicy +}; +use std::time::Duration; + +let latency_awareness_builder = LatencyAwarenessBuilder::new() + .exclusion_threshold(3.) + .update_rate(Duration::from_secs(3)) + .retry_period(Duration::from_secs(30)) + .minimum_measurements(200); + +let policy = DefaultPolicy::builder() + // Here further customisation is, of course, possible. + // e.g.: .prefer_datacenter(...) + .latency_awareness(latency_awareness_builder) + .build(); +``` + +```rust +use scylla::load_balancing::DefaultPolicy; + +let default_policy = DefaultPolicy::builder() + .prefer_datacenter("dc1".to_string()) + .token_aware(true) + .permit_dc_failover(true) + .build(); +``` + +### Node order in produced plans + +The DefaultPolicy prefers to return nodes in the following order: + +1. Alive local replicas (if token is available & token awareness is enabled) +2. Alive remote replicas (if datacenter failover is permitted & possible due to consistency constraints) +3. Alive local nodes +4. Alive remote nodes (if datacenter failover is permitted & possible due to consistency constraints) +5. Enabled down nodes +And only if latency awareness is enabled: +6. Penalised: alive local replicas, alive remote replicas, ... (in order as above). + +If no preferred datacenter is specified, all nodes are treated as local ones. + +Replicas in the same priority groups are shuffled[^1]. Non-replicas are randomly +rotated (similarly to a round robin with a random index). + +[^1]: There is an optimisation implemented for LWT requests that routes them +to the replicas in the ring order (as it prevents contention due to Paxos conflicts), so replicas in that case are not shuffled in groups at all. +In order for the optimisation to be applied, LWT statements must be prepared before. diff --git a/v0.13.0/_sources/load-balancing/load-balancing.md.txt b/v0.13.0/_sources/load-balancing/load-balancing.md.txt new file mode 100644 index 0000000000..a6b9a28e1a --- /dev/null +++ b/v0.13.0/_sources/load-balancing/load-balancing.md.txt @@ -0,0 +1,120 @@ +# Load balancing + +## Introduction + +The driver uses a load balancing policy to determine which node(s) and shard(s) +to contact when executing a query. Load balancing policies implement the +`LoadBalancingPolicy` trait, which contains methods to generate a load +balancing plan based on the query information and the state of the cluster. + +Load balancing policies do not influence to which nodes connections are +being opened. For a node connection blacklist configuration refer to +`scylla::transport::host_filter::HostFilter`, which can be set session-wide +using `SessionBuilder::host_filter` method. + +In this chapter, "target" will refer to a pair ``. + +## Plan + +When a query is prepared to be sent to the database, the load balancing policy +constructs a load balancing plan. This plan is essentially a list of targets to +which the driver will try to send the query. The first elements of the plan are +the targets which are the best to contact (e.g. they might be replicas for the +requested data or have the best latency). + +## Policy + +The Scylla/Cassandra driver provides a default load balancing policy (see +[Default Policy](default-policy.md) for details), but you can +also implement your own custom policies that better suit your specific use +case. To use a custom policy, you simply need to implement the +`LoadBalancingPolicy` trait and pass an instance of your custom policy to the +used execution profile. + +Our recommendation is to use [`Default Policy`](default-policy.md) with token- +awareness enabled and latency-awareness disabled. + +## Configuration + +Load balancing policies can be configured via execution profiles. In the code +sample provided, a new execution profile is created using +`ExecutionProfile::builder()`, and the load balancing policy is set to the +`DefaultPolicy` using `.load_balancing_policy(policy)`. + +The newly created execution profile is then converted to a handle using +`.into_handle()`, and passed as the default execution profile to the +`SessionBuilder` using `.default_execution_profile_handle(handle)`. + +```rust +use scylla::SessionBuilder; +use scylla::load_balancing::DefaultPolicy; +use scylla::transport::ExecutionProfile; +use scylla::transport::session::Session; +use std::sync::Arc; + +let policy = Arc::new(DefaultPolicy::default()); + +let profile = ExecutionProfile::builder() + .load_balancing_policy(policy) + .build(); +let handle = profile.into_handle(); + +let session: Session = SessionBuilder::new() + .known_node(&uri) + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +In addition to being able to configure load balancing policies through +execution profiles at the session level, the driver also allow for setting +execution profile handles on a per-query basis. This means that for each query, +a specific execution profile can be selected with a customized load balancing +settings. + +## `LoadBalancingPolicy` trait + +### `pick` and `fallback`: + +Most queries are sent successfully on the first try. In such cases, only the +first element of the load balancing plan is needed, so it's usually unnecessary +to compute entire load balancing plan. To optimize this common case, the +`LoadBalancingPolicy` trait provides two methods: `pick` and `fallback`. + +`pick` returns the first target to contact for a given query, which is usually +the best based on a particular load balancing policy. + +`fallback`, returns an iterator that provides the rest of the targets in the +load balancing plan. `fallback` is called when using the initial picked +target fails (or when executing speculatively) or when `pick` returned `None`. + +It's possible for the `fallback` method to include the same target that was +returned by the `pick` method. In such cases, the query execution layer filters +out the picked target from the iterator returned by `fallback`. + +### `on_query_success` and `on_query_failure`: + +The `on_query_success` and `on_query_failure` methods are useful for load +balancing policies because they provide feedback on the performance and health +of the nodes in the cluster. + +When a query is successfully executed, the `on_query_success` method is called +and can be used by the load balancing policy to update its internal state. For +example, a policy might use the latency of the successful query to update its +latency statistics for each node in the cluster. This information can be used +to make decisions about which nodes to contact in the future. + +On the other hand, when a query fails to execute, the `on_query_failure` method +is called and provides information about the failure. The error message +returned by Cassandra can help determine the cause of the failure, such as a +node being down or overloaded. The load balancing policy can use this +information to update its internal state and avoid contacting the same node +again until it's recovered. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + default-policy +``` diff --git a/v0.13.0/_sources/logging/logging.md.txt b/v0.13.0/_sources/logging/logging.md.txt new file mode 100644 index 0000000000..5b129f4cdc --- /dev/null +++ b/v0.13.0/_sources/logging/logging.md.txt @@ -0,0 +1,42 @@ +# Logging + +The driver uses the [tracing](https://github.com/tokio-rs/tracing) crate for all logs.\ +To view the logs you have to create a `tracing` subscriber to which all logs will be written. + +To just print the logs you can use the default subscriber: +```rust +use tracing::info; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Install global collector configured based on RUST_LOG env var + // This collector will receive logs from the driver + tracing_subscriber::fmt::init(); + + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + info!("Connecting to {}", uri); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + session + .query( + "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \ + {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}", + &[], + ) + .await?; + + // This query should generate a warning message + session.query("USE ks", &[]).await?; + + Ok(()) +} +``` + +To start this example execute: +```shell +RUST_LOG=info cargo run +``` + +The full [example](https://github.com/scylladb/scylla-rust-driver/tree/main/examples/logging.rs) is available in the `examples` folder \ No newline at end of file diff --git a/v0.13.0/_sources/metrics/metrics.md.txt b/v0.13.0/_sources/metrics/metrics.md.txt new file mode 100644 index 0000000000..7fb831a504 --- /dev/null +++ b/v0.13.0/_sources/metrics/metrics.md.txt @@ -0,0 +1,28 @@ +# Driver metrics + +During operation the driver collects various metrics. + +They can be accessed at any moment using `Session::get_metrics()` + +### Collected metrics: +* Query latencies +* Total number of nonpaged queries +* Number of errors during nonpaged queries +* Total number of paged queries +* Number of errors during paged queries +* Number of retries + +### Example +```rust +let metrics = session.get_metrics(); + +println!("Queries requested: {}", metrics.get_queries_num()); +println!("Iter queries requested: {}", metrics.get_queries_iter_num()); +println!("Errors occurred: {}", metrics.get_errors_num()); +println!("Iter errors occurred: {}", metrics.get_errors_iter_num()); +println!("Average latency: {}", metrics.get_latency_avg_ms().unwrap()); +println!( + "99.9 latency percentile: {}", + metrics.get_latency_percentile_ms(99.9).unwrap() +); +``` \ No newline at end of file diff --git a/v0.13.0/_sources/migration-guides/0.11-serialization.md.txt b/v0.13.0/_sources/migration-guides/0.11-serialization.md.txt new file mode 100644 index 0000000000..429a0168cf --- /dev/null +++ b/v0.13.0/_sources/migration-guides/0.11-serialization.md.txt @@ -0,0 +1,101 @@ +# Adjusting code to changes in serialization API introduced in 0.11 + +## Background + +When executing a statement through the CQL protocol, values for the bind markers are sent in a serialized, untyped form. In order to implement a safer and more robust interface, drivers can use the information returned after preparing a statement to check the type of data provided by the user against the actual types of the bind markers. + +Before 0.11, the driver couldn't do this kind of type checking. For example, in the case of non-batch queries, the only information about the user data it has is that it implements `ValueList` - defined as follows: + +```rust + +pub trait ValueList { + fn serialized(&self) -> SerializedResult<'_>; + fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError>; +} +``` + +The driver would naively serialize the data and hope that the user took care to send correct types of values. Failing to do so would, in the best case, fail on the DB-side validation; in the worst case, the data in its raw form may be reinterpreted as another type in an unintended manner. + +Another problem is that the information from the prepared statement response is required to robustly serialize user defined types, as UDTs require their fields to be serialized in the same order as they are defined in the database schema. The `IntoUserType` macro which implements Rust struct -> UDT serialization just expects that the order of the Rust struct fields matches the schema, but ensuring this can be very cumbersome for the users. + +In version 0.11, a new set of traits is introduced and the old ones are deprecated. The new traits receive more information during serialization such as names of the column/bind markers and their types, which allows to fix the issues mentioned in the previous section. + +## Old vs. new + +Both the old and the new APIs are based on three core traits: + +- `Value` - called `SerializeCql` in the new API. A type that can serialize itself to a single CQL value. For example, `i32` serializes itself into a representation that is compatible with the CQL `int` type. +- `ValueList` - called `SerializeRow` in the new API. A type that can serialize itself as a list of values for a CQL statement. For example, a `(i32, &str)` produces a list of two values which can be used in a query with two bind markers, e.g. `SELECT * FROM table WHERE pk = ? AND ck = ?`. Optionally, values in the produced list may be associated with names which is useful when using it with a query with named bind markers, e.g. `SELECT * FROM table WHERE pk = :pk AND ck = :ck`. +- `LegacyBatchValues`, previously named `BatchValues` - in new API replaced with new trait called (again) `BatchValues`. Represents a source of data for a batch request. It is essentially equivalent to a list of `ValueList`, one for each statement in the batch. For example, `((1, 2), (3, 4, 5))` can be used for a batch with two statements, the first one having two bind markers and the second one having three. + +All methods which take one of the old traits were changed to take the new trait - notably, this includes `Session::query`, `(Caching)Session::execute`, `(Caching)Session::batch`. + +The driver comes a set of `impl`s of those traits which allow to represent any CQL type (for example, see [Data Types](../data-types/data-types.md) page for a list of for which `Value` and `SerializeCql` is implemented). If the driver implements an old trait for some type, then it also provides implements the new trait for the same type. + +## Migration scenarios + +### Different default behavior in `SerializeRow`/`SerializeCql` macros + +By default, the `SerializeRow` and `SerializeCql` **will match the fields in the Rust struct by name to bind marker names** (in case of `SerializeRow`) **or UDT field names** (in case of `SerializeCql`). This is different from the old `ValueList` and `IntoUserType` macros which did not look at the field names at all and would expect the user to order the fields correctly. While the new behavior is much more ergonomic, you might have reasons not to use it. + +> **NOTE:** The deserialization macro counterparts `FromRow` and `FromUserType` have the same limitation as the old serialization macros - they require struct fields to be properly ordered. While a similar rework is planned for the deserialization traits in a future release, for the time being it might not be worth keeping the column names in sync with the database. + +In order to bring the old behavior to the new macros (the only difference being type checking which cannot be disabled right now) you can configure it using attributes, as shown in the snippet below: + +```rust +use scylla::SerializeCql; + +// The exact same attributes apply to the `SerializeRow` macro and their +// effect is completely analogous. +#[derive(SerializeCql)] +#[scylla(flavor = "enforce_order", skip_name_checks)] +struct Person { + name: String, + surname: String, + age: i16, +} +``` + +Refer to the API reference page for the `SerializeRow` and `SerializeCql` macros in the `scylla` crate to learn more about the supported attributes and their meaning. + +### Preparing is mandatory with a non-empty list of values + +> **NOTE:** The considerations in this section only concerns users of the `Session` API, `CachingSession` is not affected as it already does preparation before execute and caches the result. + +As explained in the [Background](#background) section, the driver uses data returned from the database after preparing a statement in order to implement type checking. As the new API makes type checking mandatory, **the driver must prepare the statement** so that the data for the bind markers can be type checked. It is done in case of the existing methods which used to send unprepared statements: `Session::query` and `Session::batch`. + +> **NOTE:** The driver will skip preparation if it detects that the list of values for the statement is empty, as there is nothing to be type checked. + +If you send simple statements along with non-empty lists of values, the slowdown will be as follows: + +- For `Session::query`, the driver will prepare the statement before sending it, incurring an additional round-trip. +- For `Session::batch`, the driver will send a prepare request for each *unique* unprepared statement with a non-empty list of values. **This is done serially!** + +In both cases, if the additional roundtrips are unacceptable, you should prepare the statements beforehand and reuse them - which aligns with our general recommendation against use of simple statements in performance sensitive scenarios. + +### Migrating from old to new traits *gradually* + +In some cases, migration will be as easy as changing occurrences of `IntoUserType` to `SerializeCql` and `ValueList` to `SerializeRow` and adding some atributes for procedural macros. However, if you have a large enough codebase or some custom, complicated implementations of the old traits then you might not want to migrate everything at once. To support gradual migration, the old traits were not removed but rather deprecated, and we introduced some additional utilities. + +#### Converting an object implementing an old trait to a new trait + +We provide a number of newtype wrappers: + +- `ValueAdapter` - implements `SerializeCql` if the type wrapped over implements `Value`, +- `ValueListAdapter` - implements `SerializeRow` if the type wrapped over implements `ValueList`, +- `LegacyBatchValuesAdapter` - implements `BatchValues` if the type wrapped over implements `LegacyBatchValues`. + +Note that these wrappers are not zero cost and incur some overhead: in case of `ValueAdapter` and `ValueListAdapter`, the data is first written into a newly allocated buffer and then rewritten to the final buffer. In case of `LegacyBatchValuesAdapter` there shouldn't be any additional allocations unless the implementation has an efficient, non-default `Self::LegacyBatchValuesIterator::write_next_to_request` implementation (which is not the case for the built-in `impl`s). + +Naturally, the implementations provided by the wrappers are not type safe as they directly use methods from the old traits. + +Conversion in the other direction is not possible. + +#### Custom implementations of old traits + +It is possible to directly generate an `impl` of `SerializeRow` and `SerializeCql` on a type which implements, respectively, `ValueList` or `Value`, without using the wrappers from the previous section. The following macros are provided: + +- `impl_serialize_cql_via_value` - implements `SerializeCql` if the type wrapped over implements `Value`, +- `impl_serialize_row_via_value_list` - implements `SerializeRow` if the type wrapped over implements `ValueList`, + +The implementations are practically as those generated by the wrappers described in the previous section. diff --git a/v0.13.0/_sources/migration-guides/migration-guides.md.txt b/v0.13.0/_sources/migration-guides/migration-guides.md.txt new file mode 100644 index 0000000000..86887a64c9 --- /dev/null +++ b/v0.13.0/_sources/migration-guides/migration-guides.md.txt @@ -0,0 +1,11 @@ +# Migration guides + +- [Serialization changes in version 0.11](0.11-serialization.md) + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + 0.11-serialization +``` diff --git a/v0.13.0/_sources/queries/batch.md.txt b/v0.13.0/_sources/queries/batch.md.txt new file mode 100644 index 0000000000..271c96baa1 --- /dev/null +++ b/v0.13.0/_sources/queries/batch.md.txt @@ -0,0 +1,127 @@ +# Batch statement + +A batch statement allows to execute many data-modifying statements at once.\ +These statements can be [simple](simple.md) or [prepared](prepared.md).\ +Only `INSERT`, `UPDATE` and `DELETE` statements are allowed. + +```rust +use scylla::batch::Batch; +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; + +// Create a batch statement +let mut batch: Batch = Default::default(); + +// Add a simple statement to the batch using its text +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(1, 2)"); + +// Add a simple statement created manually to the batch +let simple: Query = Query::new("INSERT INTO ks.tab (a, b) VALUES(3, 4)"); +batch.append_statement(simple); + +// Add a prepared statement to the batch +let prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a, b) VALUES(?, 6)") + .await?; +batch.append_statement(prepared); + +// Specify bound values to use with each statement +let batch_values = ((), + (), + (5_i32,)); + +// Run the batch +session.batch(&batch, batch_values).await?; +``` + +> ***Warning***\ +> Using simple statements with bind markers in batches is strongly discouraged. +> For each simple statement with a non-empty list of values in the batch, +> the driver will send a prepare request, and it will be done **sequentially**. +> Results of preparation are not cached between `Session::batch` calls. +> Consider preparing the statements before putting them into the batch. + +### Preparing a batch +Instead of preparing each statement individually, it's possible to prepare a whole batch at once: + +```rust +use scylla::batch::Batch; + +// Create a batch statement with unprepared statements +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.simple_unprepared1 VALUES(?, ?)"); +batch.append_statement("INSERT INTO ks.simple_unprepared2 VALUES(?, ?)"); + +// Prepare all statements in the batch at once +let prepared_batch: Batch = session.prepare_batch(&batch).await?; + +// Specify bound values to use with each statement +let batch_values = ((1_i32, 2_i32), + (3_i32, 4_i32)); + +// Run the prepared batch +session.batch(&prepared_batch, batch_values).await?; +``` + +### Batch options +You can set various options by operating on the `Batch` object.\ +For example to change consistency: +```rust +use scylla::batch::Batch; +use scylla::statement::Consistency; + +// Create a batch +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.tab(a) VALUES(16)"); + +// Set batch consistency to One +batch.set_consistency(Consistency::One); + +// Run the batch +session.batch(&batch, ((), )).await?; +``` + +See [Batch API documentation](https://docs.rs/scylla/latest/scylla/statement/batch/struct.Batch.html) +for more options + +### Batch values +Batch takes a tuple of values specified just like in [simple](simple.md) or [prepared](prepared.md) queries. + +Length of batch values must be equal to the number of statements in a batch.\ +Each statement must have its values specified, even if they are empty. + +Values passed to `Session::batch` must implement the trait `BatchValues`.\ +By default this includes tuples `()` and slices `&[]` of tuples and slices which implement `ValueList`. + +Example: +```rust +use scylla::batch::Batch; + +let mut batch: Batch = Default::default(); + +// A statement with two bound values +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(?, ?)"); + +// A statement with one bound value +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(3, ?)"); + +// A statement with no bound values +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(5, 6)"); + +// Batch values is a tuple of 3 tuples containing values for each statement +let batch_values = ((1_i32, 2_i32), // Tuple with two values for the first statement + (4_i32,), // Tuple with one value for the second statement + ()); // Empty tuple/unit for the third statement + +// Run the batch +// Note that the driver will prepare the first two statements, due to them +// not being prepared and having a non-empty list of values. +session.batch(&batch, batch_values).await?; +``` +For more information about sending values in a statement see [Query values](values.md) + + +### Performance +Batch statements do not use token/shard aware load balancing, batches are sent to a random node. + +Use [prepared queries](prepared.md) for best performance diff --git a/v0.13.0/_sources/queries/lwt.md.txt b/v0.13.0/_sources/queries/lwt.md.txt new file mode 100644 index 0000000000..6efc0659c4 --- /dev/null +++ b/v0.13.0/_sources/queries/lwt.md.txt @@ -0,0 +1,26 @@ +# Lightweight transaction (LWT) query + +A lightweight transaction query can be expressed just like any other query, via `Session`, with the notable difference of having an additional consistency level parameter - the `serial_consistency_level`. + + +### Format of the query +A lightweight transaction query is not a separate type - it can be expressed just like any other queries: via `SimpleQuery`, `PreparedStatement`, batches, and so on. The difference lays in the query string itself - when it contains a condition (e.g. `IF NOT EXISTS`), it becomes a lightweight transaction. It's important to remember that CQL specification requires a separate, additional consistency level to be defined for LWT queries - `serial_consistency_level`. The serial consistency level can only be set to two values: `SerialConsistency::Serial` or `SerialConsistency::LocalSerial`. The "local" variant makes the transaction consistent only within the same datacenter. For convenience, Scylla Rust Driver sets the default consistency level to `LocalSerial`, as it's more commonly used. For cross-datacenter consistency, please remember to always override the default with `SerialConsistency::Serial`. +```rust +use scylla::query::Query; +use scylla::statement::{Consistency, SerialConsistency}; + +// Create a Query manually to change the Consistency to ONE +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?) IF NOT EXISTS".to_string()); +my_query.set_consistency(Consistency::One); +// Use cross-datacenter serial consistency +my_query.set_serial_consistency(Some(SerialConsistency::Serial)); + +// Insert a value into the table +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +The rest of the API remains identical for LWT and non-LWT queries. + +See [Query API documentation](https://docs.rs/scylla/latest/scylla/statement/query/struct.Query.html) for more options + diff --git a/v0.13.0/_sources/queries/paged.md.txt b/v0.13.0/_sources/queries/paged.md.txt new file mode 100644 index 0000000000..ce6173ac72 --- /dev/null +++ b/v0.13.0/_sources/queries/paged.md.txt @@ -0,0 +1,118 @@ +# Paged query +Sometimes query results might not fit in a single page. Paged queries +allow to receive the whole result page by page. + +`Session::query_iter` and `Session::execute_iter` take a [simple query](simple.md) or a [prepared query](prepared.md) +and return an `async` iterator over result `Rows`. + +> ***Warning***\ +> In case of unprepared variant (`Session::query_iter`) if the values are not empty +> driver will first fully prepare a query (which means issuing additional request to each +> node in a cluster). This will have a performance penalty - how big it is depends on +> the size of your cluster (more nodes - more requests) and the size of returned +> result (more returned pages - more amortized penalty). In any case, it is preferable to +> use `Session::execute_iter`. + +### Examples +Use `query_iter` to perform a [simple query](simple.md) with paging: +```rust +use scylla::IntoTypedRows; +use futures::stream::StreamExt; + +let mut rows_stream = session + .query_iter("SELECT a, b FROM ks.t", &[]) + .await? + .into_typed::<(i32, i32)>(); + +while let Some(next_row_res) = rows_stream.next().await { + let (a, b): (i32, i32) = next_row_res?; + println!("a, b: {}, {}", a, b); +} +``` + +Use `execute_iter` to perform a [prepared query](prepared.md) with paging: +```rust +use scylla::IntoTypedRows; +use scylla::prepared_statement::PreparedStatement; +use futures::stream::StreamExt; + +let prepared: PreparedStatement = session + .prepare("SELECT a, b FROM ks.t") + .await?; + +let mut rows_stream = session + .execute_iter(prepared, &[]) + .await? + .into_typed::<(i32, i32)>(); + +while let Some(next_row_res) = rows_stream.next().await { + let (a, b): (i32, i32) = next_row_res?; + println!("a, b: {}, {}", a, b); +} +``` + +Query values can be passed to `query_iter` and `execute_iter` just like in a [simple query](simple.md) + +### Configuring page size +It's possible to configure the size of a single page. + +On a `Query`: +```rust +use scylla::query::Query; + +let mut query: Query = Query::new("SELECT a, b FROM ks.t"); +query.set_page_size(16); + +let _ = session.query_iter(query, &[]).await?; // ... +``` + +On a `PreparedStatement`: +```rust +use scylla::prepared_statement::PreparedStatement; + +let mut prepared: PreparedStatement = session + .prepare("SELECT a, b FROM ks.t") + .await?; + +prepared.set_page_size(16); + +let _ = session.execute_iter(prepared, &[]).await?; // ... +``` + +### Passing the paging state manually +It's possible to fetch a single page from the table, extract the paging state +from the result and manually pass it to the next query. That way, the next +query will start fetching the results from where the previous one left off. + +On a `Query`: +```rust +use scylla::query::Query; + +let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6); +let res1 = session.query(paged_query.clone(), &[]).await?; +let res2 = session + .query_paged(paged_query.clone(), &[], res1.paging_state) + .await?; +``` + +> ***Warning***\ +> If the values are not empty, driver first needs to send a `PREPARE` request +> in order to fetch information required to serialize values. This will affect +> performance because 2 round trips will be required instead of 1. + +On a `PreparedStatement`: +```rust +use scylla::query::Query; + +let paged_prepared = session + .prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7)) + .await?; +let res1 = session.execute(&paged_prepared, &[]).await?; +let res2 = session + .execute_paged(&paged_prepared, &[], res1.paging_state) + .await?; +``` + +### Performance +Performance is the same as in non-paged variants.\ +For the best performance use [prepared queries](prepared.md). \ No newline at end of file diff --git a/v0.13.0/_sources/queries/prepared.md.txt b/v0.13.0/_sources/queries/prepared.md.txt new file mode 100644 index 0000000000..e4551a2ae8 --- /dev/null +++ b/v0.13.0/_sources/queries/prepared.md.txt @@ -0,0 +1,108 @@ +# Prepared query + +Prepared queries provide much better performance than simple queries, +but they need to be prepared before use. + +```rust +use scylla::prepared_statement::PreparedStatement; + +// Prepare the query for later execution +let prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +// Run the prepared query with some values, just like a simple query +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` + +> ***Warning***\ +> For token/shard aware load balancing to work properly, all partition key values +> must be sent as bound values (see [performance section](#performance)) + +> ***Warning***\ +> Don't use `execute` to receive large amounts of data.\ +> By default the query is unpaged and might cause heavy load on the cluster. +> In such cases set a page size and use a [paged query](paged.md) instead. +> +> When page size is set, `execute` will return only the first page of results. + +### `Session::prepare` +`Session::prepare` takes query text and prepares the query on all nodes and shards. +If at least one succeeds returns success. + +### `Session::execute` +`Session::execute` takes a prepared query and bound values and runs the query. +Passing values and the result is the same as in [simple query](simple.md). + +### Query options + +To specify custom options, set them on the `PreparedStatement` before execution. +For example to change the consistency: + +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::statement::Consistency; + +// Prepare the query for later execution +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +// Set prepared query consistency to One +// This is the consistency with which this query will be executed +prepared.set_consistency(Consistency::One); + +// Run the prepared query with some values, just like a simple query +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` + +See [PreparedStatement API documentation](https://docs.rs/scylla/latest/scylla/statement/prepared_statement/struct.PreparedStatement.html) +for more options. + +> ***Note*** +> Prepared statements can be created from `Query` structs and will inherit from +> the custom options that the `Query` was created with. +> This is especially useful when using `CachingSession::execute` for example. + +### Performance + +Prepared queries have good performance, much better than simple queries. +By default they use shard/token aware load balancing. + +> **Always** pass partition key values as bound values. +> Otherwise the driver can't hash them to compute partition key +> and they will be sent to the wrong node, which worsens performance. + +Let's say we have a table like this: + +```sql +TABLE ks.prepare_table ( + a int, + b int, + c int, + PRIMARY KEY (a, b) +) +``` + +```rust +use scylla::prepared_statement::PreparedStatement; + +// WRONG - partition key value is passed in query string +// Load balancing will compute the wrong partition key +let wrong_prepared: PreparedStatement = session + .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(12345, ?, 16)") + .await?; + +session.execute(&wrong_prepared, (54321,)).await?; + +// GOOD - partition key values are sent as bound values +// Other values can be sent any way you like, it doesn't matter +let good_prepared: PreparedStatement = session + .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(?, ?, 16)") + .await?; + +session.execute(&good_prepared, (12345, 54321)).await?; + +``` diff --git a/v0.13.0/_sources/queries/queries.md.txt b/v0.13.0/_sources/queries/queries.md.txt new file mode 100644 index 0000000000..b75810d0ad --- /dev/null +++ b/v0.13.0/_sources/queries/queries.md.txt @@ -0,0 +1,39 @@ +# Making queries + +This driver supports all query types available in Scylla: +* [Simple queries](simple.md) + * Easy to use + * Poor performance + * Primitive load balancing +* [Prepared queries](prepared.md) + * Need to be prepared before use + * Fast + * Properly load balanced +* [Batch statements](batch.md) + * Run multiple queries at once + * Can be prepared for better performance and load balancing +* [Paged queries](paged.md) + * Allows to read result in multiple pages when it doesn't fit in a single response + * Can be prepared for better performance and load balancing + +Additionally there is special functionality to enable `USE KEYSPACE` queries: +[USE keyspace](usekeyspace.md) + +Queries are fully asynchronous - you can run as many of them in parallel as you wish. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + simple + values + result + prepared + batch + paged + usekeyspace + schema-agreement + lwt + timeouts +``` diff --git a/v0.13.0/_sources/queries/result.md.txt b/v0.13.0/_sources/queries/result.md.txt new file mode 100644 index 0000000000..0374599301 --- /dev/null +++ b/v0.13.0/_sources/queries/result.md.txt @@ -0,0 +1,115 @@ +# Query result + +`Session::query` and `Session::execute` return a `QueryResult` with rows represented as `Option>`. + +### Basic representation +`Row` is a basic representation of a received row. It can be used by itself, but it's a bit awkward to use: +```rust +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows { + let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap(); + } +} +``` + +### Parsing using `into_typed` +The driver provides a way to parse a row as a tuple of Rust types: +```rust +use scylla::IntoTypedRows; + +// Parse row as a single column containing an int value +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows { + let (int_value,): (i32,) = row.into_typed::<(i32,)>()?; + } +} + +// rows.into_typed() converts a Vec of Rows to an iterator of parsing results +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32,)>() { + let (int_value,): (i32,) = row?; + } +} + +// Parse row as two columns containing an int and text columns +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32, String)>() { + let (int_value, text_value): (i32, String) = row?; + } +} +``` + +## Parsing using convenience methods +[`QueryResult`](https://docs.rs/scylla/latest/scylla/transport/query_result/struct.QueryResult.html) provides convenience methods for parsing rows. +Here are a few of them: +* `rows_typed::()` - returns the rows parsed as the given type +* `maybe_first_row_typed::` - returns `Option` containing first row from the result +* `first_row_typed::` - same as `maybe_first_row`, but fails without the first row +* `single_row_typed::` - same as `first_row`, but fails when there is more than one row +* `result_not_rows()` - ensures that query response was not `rows`, helps avoid bugs + + +```rust +// Parse row as a single column containing an int value +let rows = session + .query("SELECT a from ks.tab", &[]) + .await? + .rows_typed::<(i32,)>()?; // Same as .rows()?.into_typed() +for row in rows { + let (int_value,): (i32,) = row?; +} + +// maybe_first_row_typed gets the first row and parses it as the given type +let first_int_val: Option<(i32,)> = session + .query("SELECT a from ks.tab", &[]) + .await? + .maybe_first_row_typed::<(i32,)>()?; + +// no_rows fails when the response is rows +session.query("INSERT INTO ks.tab (a) VALUES (0)", &[]).await?.result_not_rows()?; +``` +For more see [`QueryResult`](https://docs.rs/scylla/latest/scylla/transport/query_result/struct.QueryResult.html) + +### `NULL` values +`NULL` values will return an error when parsed as a Rust type. +To properly handle `NULL` values parse column as an `Option<>`: +```rust +use scylla::IntoTypedRows; + +// Parse row as two columns containing an int and text which might be null +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::<(i32, Option)>() { + let (int_value, str_or_null): (i32, Option) = row?; + } +} +``` + +### Parsing row as a custom struct +It is possible to receive row as a struct with fields matching the columns.\ +The struct must: +* have the same number of fields as the number of queried columns +* have field types matching the columns being received +* derive `FromRow` + +Field names don't need to match column names. +```rust +use scylla::IntoTypedRows; +use scylla::macros::FromRow; +use scylla::frame::response::cql_to_rust::FromRow; + +#[derive(FromRow)] +struct MyRow { + age: i32, + name: Option +} + +// Parse row as two columns containing an int and text which might be null +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows { + for row in rows.into_typed::() { + let my_row: MyRow = row?; + } +} +``` + +### Other data types +For parsing other data types see [Data Types](../data-types/data-types.md) \ No newline at end of file diff --git a/v0.13.0/_sources/queries/schema-agreement.md.txt b/v0.13.0/_sources/queries/schema-agreement.md.txt new file mode 100644 index 0000000000..a7163af7dd --- /dev/null +++ b/v0.13.0/_sources/queries/schema-agreement.md.txt @@ -0,0 +1,53 @@ +# Schema agreement + +Sometimes after performing queries some nodes have not been updated, so we need a mechanism that checks if every node have agreed on schema version. + +### Automated awaiting schema agreement + +The driver automatically awaits schema agreement after a schema-altering query is executed. +Waiting for schema agreement more than necessary is never a bug, but might slow down applications which do a lot of schema changes (e.g. a migration). +For instance, in case where somebody wishes to create a keyspace and then a lot of tables in it, it makes sense only to wait after creating a keyspace +and after creating all the tables rather than after every query. Therefore, the said behaviour can be disabled: + +```rust +let session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .auto_await_schema_agreement(false) + .build() + .await?; +``` + +### Manually awaiting schema agreement + +`Session::await_schema_agreement` returns a `Future` that can be `await`ed as long as schema is not in an agreement. +However, it won't wait forever; `SessionConfig` defines a timeout that limits the time of waiting. If the timeout elapses, +the return value is `Err(QueryError::RequestTimeout)`, otherwise it is `Ok(schema_version)`. + +```rust +session.await_schema_agreement().await?; +``` + +### Interval of checking for schema agreement + +If the schema is not agreed upon, the driver sleeps for a duration before checking it again. The default value is 200 milliseconds, +but it can be changed with `SessionBuilder::schema_agreement_interval`. + +```rust +SessionBuilder::new() + .known_node("127.0.0.1:9042") + .schema_agreement_interval(Duration::from_secs(1)) + .build() + .await?; +``` + +### Checking if schema is in agreement now + +If you want to check if schema is in agreement now, without retrying after failure, you can use `Session::check_schema_agreement` function. + +```rust +if session.check_schema_agreement().await?.is_some() { + println!("SCHEMA AGREED"); +} else { + println!("SCHEMA IS NOT IN AGREEMENT"); +} +``` diff --git a/v0.13.0/_sources/queries/simple.md.txt b/v0.13.0/_sources/queries/simple.md.txt new file mode 100644 index 0000000000..cb6de9eb22 --- /dev/null +++ b/v0.13.0/_sources/queries/simple.md.txt @@ -0,0 +1,82 @@ +# Simple query + +Simple query takes query text and values and simply executes them on a `Session`: +```rust +// Insert a value into the table +let to_insert: i32 = 12345; +session + .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,)) + .await?; +``` + +> ***Warning***\ +> Don't use simple query to receive large amounts of data.\ +> By default the query is unpaged and might cause heavy load on the cluster.\ +> In such cases set a page size and use [paged query](paged.md) instead.\ +> +> When page size is set, `query` will return only the first page of results. + +> ***Warning***\ +> If the values are not empty, driver first needs to send a `PREPARE` request +> in order to fetch information required to serialize values. This will affect +> performance because 2 round trips will be required instead of 1. + +### First argument - the query +As the first argument `Session::query` takes anything implementing `Into`.\ +You can create a query manually to set custom options. For example to change query consistency: +```rust +use scylla::query::Query; +use scylla::statement::Consistency; + +// Create a Query manually to change the Consistency to ONE +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_consistency(Consistency::One); + +// Insert a value into the table +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` +See [Query API documentation](https://docs.rs/scylla/latest/scylla/statement/query/struct.Query.html) for more options + +### Second argument - the values +Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.\ +Each `?` in query text will be filled with the matching value. + +The easiest way is to pass values using a tuple: +```rust +// Sending an integer and a string using a tuple +session + .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, 'text2')", (2_i32, "Some text")) + .await?; +``` +Here the first `?` will be filled with `2` and the second with `"Some text"`. +> **Never** pass values by adding strings, this could lead to [SQL Injection](https://en.wikipedia.org/wiki/SQL_injection) + +See [Query values](values.md) for more information about sending values in queries + +### Query result +`Session::query` returns `QueryResult` with rows represented as `Option>`.\ +Each row can be parsed as a tuple of rust types using `rows_typed`: +```rust +use scylla::IntoTypedRows; + +// Query rows from the table and print them +let result = session.query("SELECT a FROM ks.tab", &[]).await?; +let mut iter = result.rows_typed::<(i32,)>()?; +while let Some(read_row) = iter.next().transpose()? { + println!("Read a value from row: {}", read_row.0); +} +``` +> In cases where page size is set, simple query returns only a single page of results.\ +> To receive all pages use a [paged query](paged.md) instead.\ + +See [Query result](result.md) for more information about handling query results + +### Performance +Simple queries should not be used in places where performance matters.\ +If performance matters use a [Prepared query](prepared.md) instead. + +With simple query the database has to parse query text each time it's executed, which worsens performance.\ + +Additionally token and shard aware load balancing does not work with simple queries. They are sent to random nodes. diff --git a/v0.13.0/_sources/queries/timeouts.md.txt b/v0.13.0/_sources/queries/timeouts.md.txt new file mode 100644 index 0000000000..16e4af1ca3 --- /dev/null +++ b/v0.13.0/_sources/queries/timeouts.md.txt @@ -0,0 +1,53 @@ +# Query timeouts + +Query execution time can be limited by setting a request timeout. If a query does not complete +in the given time, then `QueryError::RequestTimeout` is returned by the driver immediately, +so that application logic can continue operating, but the query may still be in progress on the server. + +As a side note, if one wishes custom server-side timeouts (i.e. actual interruption of query processing), +one can use a[`USING TIMEOUT ` directive supported in ScyllaDB](https://github.com/scylladb/scylladb/blob/master/docs/cql/cql-extensions.md#using-timeout) +(but not in Cassandra). + +Timeout can be set globally (per session) or locally (for given statement). +The default per-session timeout is currently 30s. +It is possible to turn off timeouts completely by providing `None` as timeout when building `Session`. +However, setting per-statement timeout to `None` results in falling back to per-session timeout. + +```rust +use scylla::{Session, SessionBuilder, query::Query}; +use scylla::transport::ExecutionProfile; +use std::time::Duration; + +let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + +let no_timeout_profile_handle = ExecutionProfile::builder() + .request_timeout(None) // no timeout + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node(uri) + .default_execution_profile_handle(no_timeout_profile_handle) // no per-session timeout + .build() + .await?; + +// This query, having no timeout, could block indefinitely if a queried node hangs. +session + .query("TRUNCATE keyspace.table", ()) + .await?; + +let three_sec_timeout_profile_handle = ExecutionProfile::builder() + .request_timeout(Some(Duration::from_secs(3))) // no timeout + .build() + .into_handle(); + +// The below query will last for no more than 3 seconds, yielding a RequestTimeout error +// if no response arrives until then. +let mut query: Query = "TRUNCATE keyspace.table".into(); +query.set_execution_profile_handle(Some(three_sec_timeout_profile_handle)); +session + .query(query, ()) + .await?; + +``` diff --git a/v0.13.0/_sources/queries/usekeyspace.md.txt b/v0.13.0/_sources/queries/usekeyspace.md.txt new file mode 100644 index 0000000000..7b9afabeb6 --- /dev/null +++ b/v0.13.0/_sources/queries/usekeyspace.md.txt @@ -0,0 +1,77 @@ +# USE keyspace + +Using a keyspace allows to omit keyspace name in queries. + +For example in `cqlsh` one could write: +```sql +cqlsh> SELECT * FROM my_keyspace.table; + + a | b | +-------+-------+ + 12345 | 54321 | + +(1 rows) +cqlsh> USE my_keyspace; +cqlsh:my_keyspace> SELECT * FROM table; + + a | b | +-------+-------+ + 12345 | 54321 | + +(1 rows) + +``` +Tables from other keyspaces can still easily be accessed by using their keyspace names. +```sql +cqlsh:my_keyspace> SELECT * FROM other_keyspace.other_table; +``` + +In the driver this can be achieved using `Session::use_keyspace`: +```rust +session + .query("INSERT INTO my_keyspace.tab (a) VALUES ('test1')", &[]) + .await?; + +session.use_keyspace("my_keyspace", false).await?; + +// Now we can omit keyspace name in the query +session + .query("INSERT INTO tab (a) VALUES ('test2')", &[]) + .await?; +``` + +The first argument is the keyspace name.\ +The second argument states whether this name is case sensitive. + +It is also possible to send raw use keyspace query using `Session::query` instead of `Session::use_keyspace` such as: +```rust +session.query("USE my_keyspace", &[]).await?; +``` +This method has a slightly worse latency than `Session::use_keyspace` - there are two roundtrips needed instead of one. +Therefore, `Session::use_keyspace` is the preferred method for setting keyspaces. + +### Multiple use queries at once +Don't run multiple `use_keyspace` queries at once. +This could end up with half of connections using one keyspace and the other half using the other. + +### Case sensitivity + +In CQL a keyspace name can be case insensitive (without `"`) or case sensitive (with `"`).\ +If the second argument to `use_keyspace` is set to `true` this keyspace name will be wrapped in `"`.\ +It is best to avoid the problem altogether and just not create two keyspaces with the same name but different cases. + +Let's see what happens when there are two keyspaces with the same name but different cases: `my_keyspace` and `MY_KEYSPACE`: + +```rust +// lowercase name without case sensitivity will use my_keyspace +session.use_keyspace("my_keyspace", false).await?; + +// lowercase name with case sensitivity will use my_keyspace +session.use_keyspace("my_keyspace", true).await?; + +// uppercase name without case sensitivity will use my_keyspace +session.use_keyspace("MY_KEYSPACE", false).await?; + +// uppercase name with case sensitivity will use MY_KEYSPACE +session.use_keyspace("MY_KEYSPACE", true).await?; +``` diff --git a/v0.13.0/_sources/queries/values.md.txt b/v0.13.0/_sources/queries/values.md.txt new file mode 100644 index 0000000000..caddca4036 --- /dev/null +++ b/v0.13.0/_sources/queries/values.md.txt @@ -0,0 +1,125 @@ +# Query values +Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.\ +Each `?` in query text will be filled with the matching value. + +> **Never** pass values by adding strings, this could lead to [SQL Injection](https://en.wikipedia.org/wiki/SQL_injection) + +Each list of values to send in a query must implement the trait `SerializeRow`.\ +By default this can be a slice `&[]`, a tuple `()` (max 16 elements) of values to send, +or a custom struct which derives from `SerializeRow`. + +A few examples: +```rust +// Empty slice means that there are no values to send +session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?; + +// Empty tuple/unit also means that there are no values to send +session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?; + +// Sending three integers using a slice: +session + .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref()) + .await?; + +// Sending an integer and a string using a tuple +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text")) + .await?; + +// Sending an integer and a string using a named struct. +// Names of fields must match names of columns in request, +// but having them in the same order is not required. +// If the fields are in the same order, you can use attribute: +// `#[scylla(flavor = "enforce_order")]` +// in order to skip sorting the fields and just check if they +// are in the same order. See documentation of this macro +// for more information. +#[derive(SerializeRow)] +struct IntString { + a: i32, + b: String, +} + +let int_string = IntString { + a: 42_i32, + b: "hello".to_owned(), +}; + +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string) + .await?; + +// You can use named bind markers in query if you want +// your names in struct to be different than column names. +#[derive(SerializeRow)] +struct IntStringCustom { + first_value: i32, + second_value: String, +} + +let int_string_custom = IntStringCustom { + first_value: 42_i32, + second_value: "hello".to_owned(), +}; + +session + .query("INSERT INTO ks.tab (a, b) VALUES(:first_value, :second_value)", int_string_custom) + .await?; + +// Sending a single value as a tuple requires a trailing coma (Rust syntax): +session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?; + +// Each value can also be sent using a reference: +session + .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text")) + .await?; + +// A map of named values can also be provided: +let mut vals: HashMap<&str, CqlValue> = HashMap::new(); +vals.insert("avalue", CqlValue::Text("hello".to_string())); +vals.insert("bvalue", CqlValue::Int(17)); +session + .query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals) + .await?; + +``` + +### `NULL` values +Null values can be sent using `Option<>` - sending a `None` will make the value `NULL`: +```rust +let null_i32: Option = None; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,)) + .await?; +``` + +### `Unset` values +When performing an insert with values which might be `NULL`, it's better to use `Unset`.\ +Database treats inserting `NULL` as a delete operation and will generate a tombstone. +Using `Unset` results in better performance: + +```rust +use scylla::frame::value::{MaybeUnset, Unset}; + +// Inserting a null results in suboptimal performance +let null_i32: Option = None; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,)) + .await?; + +// Using MaybeUnset enum is better +let unset_i32: MaybeUnset = MaybeUnset::Unset; +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,)) + .await?; + +// If we are sure that a value should be unset we can simply use Unset +session + .query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,)) + .await?; +``` +See the [issue](https://issues.apache.org/jira/browse/CASSANDRA-7304) for more information about `Unset` + +### Other data types +See [Data Types](../data-types/data-types.md) for instructions on sending other data types diff --git a/v0.13.0/_sources/quickstart/create-project.md.txt b/v0.13.0/_sources/quickstart/create-project.md.txt new file mode 100644 index 0000000000..41f9b6228f --- /dev/null +++ b/v0.13.0/_sources/quickstart/create-project.md.txt @@ -0,0 +1,34 @@ +# Creating a project + +To create a new project run: +```shell +cargo new myproject +``` + +In `Cargo.toml` add useful dependencies: +```toml +[dependencies] +scylla = "0.13" +tokio = { version = "1.12", features = ["full"] } +futures = "0.3.6" +uuid = "1.0" +bigdecimal = "0.4" +num-bigint = "0.3" +tracing = "0.1.36" +tracing-subscriber = { version = "0.3.14", features = ["env-filter"] } +``` + +In `main.rs` put: +```rust +use scylla::Session; + +#[tokio::main] +async fn main() { + println!("Hello scylla!"); +} +``` + +Now running `cargo run` should print: +```shell +Hello scylla! +``` diff --git a/v0.13.0/_sources/quickstart/example.md.txt b/v0.13.0/_sources/quickstart/example.md.txt new file mode 100644 index 0000000000..a543c7d40b --- /dev/null +++ b/v0.13.0/_sources/quickstart/example.md.txt @@ -0,0 +1,52 @@ +# Connecting and running a simple query + +Now everything is ready to use the driver. +Here is a small example: +```rust +use scylla::{IntoTypedRows, Session, SessionBuilder}; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new Session which connects to node at 127.0.0.1:9042 + // (or SCYLLA_URI if specified) + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new() + .known_node(uri) + .build() + .await?; + + // Create an example keyspace and table + session + .query( + "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \ + {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}", + &[], + ) + .await?; + + session + .query( + "CREATE TABLE IF NOT EXISTS ks.extab (a int primary key)", + &[], + ) + .await?; + + // Insert a value into the table + let to_insert: i32 = 12345; + session + .query("INSERT INTO ks.extab (a) VALUES(?)", (to_insert,)) + .await?; + + // Query rows from the table and print them + let result = session.query("SELECT a FROM ks.extab", &[]).await?; + let mut iter = result.rows_typed::<(i32,)>()?; + while let Some(read_row) = iter.next().transpose()? { + println!("Read a value from row: {}", read_row.0); + } + + Ok(()) +} +``` diff --git a/v0.13.0/_sources/quickstart/quickstart.md.txt b/v0.13.0/_sources/quickstart/quickstart.md.txt new file mode 100644 index 0000000000..b544aef743 --- /dev/null +++ b/v0.13.0/_sources/quickstart/quickstart.md.txt @@ -0,0 +1,23 @@ + +# Quick Start + + +In this chapter we will set up a Rust project and run a few simple queries. + +Topics Include: + +* [Create a Rust Project](create-project.md) +* [Example](example.md) +* [Install Scylla with Docker](scylla-docker.md) + + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + create-project + example + scylla* + +``` \ No newline at end of file diff --git a/v0.13.0/_sources/quickstart/scylla-docker.md.txt b/v0.13.0/_sources/quickstart/scylla-docker.md.txt new file mode 100644 index 0000000000..849bcbc10e --- /dev/null +++ b/v0.13.0/_sources/quickstart/scylla-docker.md.txt @@ -0,0 +1,23 @@ +# Running Scylla using Docker + +To make queries we will need a running Scylla instance. The easiest way is to use a [Docker](https://www.docker.com/) image.\ +Please [install Docker](https://docs.docker.com/engine/install) if it's not installed. + +### Running scylla +To start Scylla run: +```bash +# on Linux sudo might be required +docker run --rm -it -p 9042:9042 scylladb/scylla --smp 2 +``` + +Docker will download the image, then after minute or two there should be a message like: +```shell +Starting listening for CQL clients on 172.17.0.2:9042 +``` +This means that Scylla is ready to receive queries + +To stop this instance press `Ctrl + C` + +### More information +More information about this image can be found on [dockerhub](https://hub.docker.com/r/scylladb/scylla) + diff --git a/v0.13.0/_sources/retry-policy/default.md.txt b/v0.13.0/_sources/retry-policy/default.md.txt new file mode 100644 index 0000000000..590b503730 --- /dev/null +++ b/v0.13.0/_sources/retry-policy/default.md.txt @@ -0,0 +1,69 @@ +# Default retry policy +This is the retry policy used by default. It retries when there is a high chance that it might help.\ +This policy is based on the one in [DataStax Java Driver](https://docs.datastax.com/en/developer/java-driver/4.11/manual/core/retries/). +The behaviour is the same. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new()))); + +// You can also set retry policy in an execution profile +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::DefaultRetryPolicy; + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; +prepared.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new()))); + +// You can also set retry policy in an execution profile +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DefaultRetryPolicy::new())) + .build() + .into_handle(); +prepared.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/v0.13.0/_sources/retry-policy/downgrading-consistency.md.txt b/v0.13.0/_sources/retry-policy/downgrading-consistency.md.txt new file mode 100644 index 0000000000..a13aea35f0 --- /dev/null +++ b/v0.13.0/_sources/retry-policy/downgrading-consistency.md.txt @@ -0,0 +1,108 @@ +# Downgrading consistency retry policy + +A retry policy that sometimes retries with a lower consistency level than the one initially +requested. +**BEWARE**: this policy may retry queries using a lower consistency level than the one +initially requested. By doing so, it may break consistency guarantees. In other words, if you use +this retry policy, there are cases (documented below) where a read at `Consistency::Quorum` **may +not** see a preceding write at `Consistency::Quorum`. Do not use this policy unless you have +understood the cases where this can happen and are ok with that. It is also highly recommended to +always log the occurrences of such consistency breaks. +This policy implements the same retries than the [DefaultRetryPolicy](default.md) policy. But on top +of that, it also retries in the following cases: + - On a read timeout: if the number of replicas that responded is greater than one, but lower + than is required by the requested consistency level, the operation is retried at a lower + consistency level. + - On a write timeout: if the operation is a `WriteType::UnloggedBatch` and at least one + replica acknowledged the write, the operation is retried at a lower consistency level. + Furthermore, for other operations, if at least one replica acknowledged the write, the + timeout is ignored. + - On an unavailable exception: if at least one replica is alive, the operation is retried at + a lower consistency level. + +The lower consistency level to use for retries is determined by the following rules: + - if more than 3 replicas responded, use `Consistency::Three`. + - if 1, 2 or 3 replicas responded, use the corresponding level `Consistency::One`, `Consistency::Two` or + `Consistency::Three`. + +Note that if the initial consistency level was `Consistency::EachQuorum`, Scylla returns the number +of live replicas _in the datacenter that failed to reach consistency_, not the overall +number in the cluster. Therefore if this number is 0, we still retry at `Consistency::One`, on the +assumption that a host may still be up in another datacenter. +The reasoning being this retry policy is the following one. If, based on the information the +Scylla coordinator node returns, retrying the operation with the initially requested +consistency has a chance to succeed, do it. Otherwise, if based on this information we know +**the initially requested consistency level cannot be achieved currently**, then: + - For writes, ignore the exception (thus silently failing the consistency requirement) if we + know the write has been persisted on at least one replica. + - For reads, try reading at a lower consistency level (thus silently failing the consistency + requirement). +In other words, this policy implements the idea that if the requested consistency level cannot be +achieved, the next best thing for writes is to make sure the data is persisted, and that reading +something is better than reading nothing, even if there is a risk of reading stale data. + +This policy is based on the one in [DataStax Java Driver](https://docs.datastax.com/en/drivers/java/3.11/com/datastax/driver/core/policies/DowngradingConsistencyRetryPolicy.html). +The behaviour is the same. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new())) + .build() + .into_handle(); + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +prepared.set_execution_profile_handle(Some(handle)); + + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/v0.13.0/_sources/retry-policy/fallthrough.md.txt b/v0.13.0/_sources/retry-policy/fallthrough.md.txt new file mode 100644 index 0000000000..ca4cd44947 --- /dev/null +++ b/v0.13.0/_sources/retry-policy/fallthrough.md.txt @@ -0,0 +1,65 @@ +# Fallthrough retry policy + +The `FalthroughRetryPolicy` never retries, returns errors straight to the user. Useful for debugging. + +### Examples +To use in `Session`: +```rust +use scylla::{Session, SessionBuilder}; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` + +To use in a [simple query](../queries/simple.md): +```rust +use scylla::query::Query; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +// Create a Query manually and set the retry policy +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)"); +my_query.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.query(my_query, (to_insert,)).await?; +``` + +To use in a [prepared query](../queries/prepared.md): +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::ExecutionProfile; +use scylla::transport::retry_policy::FallthroughRetryPolicy; + +let handle = ExecutionProfile::builder() + .retry_policy(Box::new(FallthroughRetryPolicy::new())) + .build() + .into_handle(); + +// Create PreparedStatement manually and set the retry policy +let mut prepared: PreparedStatement = session + .prepare("INSERT INTO ks.tab (a) VALUES(?)") + .await?; + +prepared.set_execution_profile_handle(Some(handle)); + +// Run the query using this retry policy +let to_insert: i32 = 12345; +session.execute(&prepared, (to_insert,)).await?; +``` diff --git a/v0.13.0/_sources/retry-policy/retry-policy.md.txt b/v0.13.0/_sources/retry-policy/retry-policy.md.txt new file mode 100644 index 0000000000..68c4726dc0 --- /dev/null +++ b/v0.13.0/_sources/retry-policy/retry-policy.md.txt @@ -0,0 +1,48 @@ +# Retry policy configuration + +After a query fails the driver might decide to retry it based on its `Retry Policy` and the query itself. +Retry policy can be configured for `Session` or just for a single query. + +### Retry policies +By default there are three retry policies: +* [Fallthrough Retry Policy](fallthrough.md) - never retries, returns all errors straight to the user +* [Default Retry Policy](default.md) - used by default, might retry if there is a high chance of success +* [Downgrading Consistency Retry Policy](downgrading-consistency.md) - behaves as [Default Retry Policy](default.md), but also, + in some more cases, it retries **with lower `Consistency`**. + +It's possible to implement a custom `Retry Policy` by implementing the traits `RetryPolicy` and `RetrySession`. + +### Query idempotence +A query is idempotent if it can be applied multiple times without changing the result of the initial application + +Specifying that a query is idempotent increases the chances that it will be retried in case of failure. +Idempotent queries can be retried in situations where retrying non idempotent queries would be dangerous. + +Idempotence has to be specified manually, the driver is not able to figure it out by itself. +```rust +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; + +// Specify that a Query is idempotent +let mut my_query: Query = Query::new("SELECT a FROM ks.tab"); +my_query.set_is_idempotent(true); + + +// Specify that a PreparedStatement is idempotent +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +prepared.set_is_idempotent(true); +``` + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + fallthrough + default + downgrading-consistency + +``` diff --git a/v0.13.0/_sources/schema/schema.md.txt b/v0.13.0/_sources/schema/schema.md.txt new file mode 100644 index 0000000000..19a5bc9751 --- /dev/null +++ b/v0.13.0/_sources/schema/schema.md.txt @@ -0,0 +1,60 @@ +# Schema + +The driver is capable of fetching database schema and presenting it to its users. + +## Fetching schema + +Fetching database schema occurs periodically, but it can also be done on-demand. In order to fetch the newest database schema, one can call `refresh_metadata()` on a Session instance: +```rust + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + // Schema metadata will be fetched below + session.refresh_metadata().await?; + Ok(()) +} +``` + +## Inspecting schema + +Once fetched, a snapshot of cluster's schema can be examined. The following information can be obtained: + - keyspace + - tables belonging to the keyspace + - materialized views belonging to the keyspace + - replication strategy + - user-defined types + - table/view + - primary key definition + - columns + - partitioner type + +Example showing how to print obtained schema information: + +```rust + +#[tokio::main] +async fn main() -> Result<(), Box> { + let uri = std::env::var("SCYLLA_URI") + .unwrap_or_else(|_| "127.0.0.1:9042".to_string()); + + let session: Session = SessionBuilder::new().known_node(uri).build().await?; + // Schema metadata will be fetched below + session.refresh_metadata().await?; + + let cluster_data = &session.get_cluster_data(); + let keyspaces = &cluster_data.get_keyspace_info(); + + for (keyspace_name, keyspace_info) in keyspaces.iter() { + println!("Keyspace {}:", keyspace_name); + println!("\tTables: {:#?}", keyspace_info.tables); + println!("\tViews: {:#?}", keyspace_info.views); + println!("\tUDTs: {:#?}", keyspace_info.user_defined_types); + } + + Ok(()) +} +``` diff --git a/v0.13.0/_sources/speculative-execution/percentile.md.txt b/v0.13.0/_sources/speculative-execution/percentile.md.txt new file mode 100644 index 0000000000..c82c24a925 --- /dev/null +++ b/v0.13.0/_sources/speculative-execution/percentile.md.txt @@ -0,0 +1,34 @@ +# Percentile speculative execution + +This policy has access to `Metrics` shared with session, and triggers +speculative execution when the request to the current host is above a +given percentile. + + +### Example +To use this policy in `Session`: +```rust +use std::{sync::Arc, time::Duration}; +use scylla::{ + Session, + SessionBuilder, + speculative_execution::PercentileSpeculativeExecutionPolicy, + transport::execution_profile::ExecutionProfile, +}; + +let policy = PercentileSpeculativeExecutionPolicy { + max_retry_count: 3, + percentile: 99.0, +}; + +let handle = ExecutionProfile::builder() + .speculative_execution_policy(Some(Arc::new(policy))) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` diff --git a/v0.13.0/_sources/speculative-execution/simple.md.txt b/v0.13.0/_sources/speculative-execution/simple.md.txt new file mode 100644 index 0000000000..dd17db55d6 --- /dev/null +++ b/v0.13.0/_sources/speculative-execution/simple.md.txt @@ -0,0 +1,34 @@ +# Simple speculative execution + +The easiest speculative execution policy available. It starts another +execution of a query after constant delay of `retry_interval` and does at most +`max_retry_count` speculative query executions (not counting the first, +non-speculative one). + +### Example +To use this policy in `Session`: +```rust +use std::{sync::Arc, time::Duration}; +use scylla::{ + Session, + SessionBuilder, + speculative_execution::SimpleSpeculativeExecutionPolicy, + transport::execution_profile::ExecutionProfile, +}; + +let policy = SimpleSpeculativeExecutionPolicy { + max_retry_count: 3, + retry_interval: Duration::from_millis(100), +}; + +let handle = ExecutionProfile::builder() + .speculative_execution_policy(Some(Arc::new(policy))) + .build() + .into_handle(); + +let session: Session = SessionBuilder::new() + .known_node("127.0.0.1:9042") + .default_execution_profile_handle(handle) + .build() + .await?; +``` diff --git a/v0.13.0/_sources/speculative-execution/speculative.md.txt b/v0.13.0/_sources/speculative-execution/speculative.md.txt new file mode 100644 index 0000000000..d6e2ae0422 --- /dev/null +++ b/v0.13.0/_sources/speculative-execution/speculative.md.txt @@ -0,0 +1,26 @@ +# Speculative execution + +Speculative query execution is an optimization technique where a driver +pre-emptively starts a second execution of a query against another node, +before the first node has replied. + +There are multiple speculative execution strategies that the driver can use. +Speculative execution can be configured for the whole whole `Session` during +its creation. + +Available speculative execution strategies: +* [Simple](simple.md) +* [Latency Percentile](percentile.md) + +Speculative execution is not enabled by default, and currently only +non-iter session methods use it. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + simple + percentile + +``` \ No newline at end of file diff --git a/v0.13.0/_sources/tracing/basic.md.txt b/v0.13.0/_sources/tracing/basic.md.txt new file mode 100644 index 0000000000..73a6cb227c --- /dev/null +++ b/v0.13.0/_sources/tracing/basic.md.txt @@ -0,0 +1,74 @@ +# Tracing a simple/prepared/batch query + +[Simple query](../queries/simple.md), [prepared query](../queries/prepared.md) and [batch query](../queries/batch.md) +return a `QueryResult` which contains a `tracing_id` if tracing was enabled. + +### Tracing a simple query +```rust +use scylla::query::Query; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Create a Query manually and enable tracing +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)"); +query.set_tracing(true); + +let res: QueryResult = session.query(query, &[]).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing a prepared query +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Prepare the query +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +// Enable tracing for the prepared query +prepared.set_tracing(true); + +let res: QueryResult = session.execute(&prepared, &[]).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing a batch query +```rust +use scylla::batch::Batch; +use scylla::QueryResult; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Create a batch statement +let mut batch: Batch = Default::default(); +batch.append_statement("INSERT INTO ks.tab (a) VALUES(4)"); + +// Enable tracing +batch.set_tracing(true); + +let res: QueryResult = session.batch(&batch, ((),)).await?; +let tracing_id: Option = res.tracing_id; + +if let Some(id) = tracing_id { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(&id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/v0.13.0/_sources/tracing/paged.md.txt b/v0.13.0/_sources/tracing/paged.md.txt new file mode 100644 index 0000000000..e7424e6ddd --- /dev/null +++ b/v0.13.0/_sources/tracing/paged.md.txt @@ -0,0 +1,65 @@ +# Tracing a paged query + +A paged query performs multiple simple/prepared queries to query subsequent pages.\ +If tracing is enabled the row iterator will contain a list of tracing ids for all performed queries. + + +### Tracing `Session::query_iter` +```rust +use scylla::query::Query; +use scylla::transport::iterator::RowIterator; +use scylla::tracing::TracingInfo; +use futures::StreamExt; +use uuid::Uuid; + +// Create a Query manually and enable tracing +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)"); +query.set_tracing(true); + +// Create a paged query iterator and fetch pages +let mut row_iterator: RowIterator = session.query_iter(query, &[]).await?; +while let Some(_row) = row_iterator.next().await { + // Receive rows +} + +// Now there are tracing ids for each performed query +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids(); + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` + +### Tracing `Session::execute_iter` +```rust +use scylla::prepared_statement::PreparedStatement; +use scylla::transport::iterator::RowIterator; +use scylla::tracing::TracingInfo; +use futures::StreamExt; +use uuid::Uuid; + +// Prepare the query +let mut prepared: PreparedStatement = session + .prepare("SELECT a FROM ks.tab") + .await?; + +// Enable tracing for the prepared query +prepared.set_tracing(true); + +// Create a paged query iterator and fetch pages +let mut row_iterator: RowIterator = session.execute_iter(prepared, &[]).await?; +while let Some(_row) = row_iterator.next().await { + // Receive rows +} + +// Now there are tracing ids for each performed query +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids(); + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/v0.13.0/_sources/tracing/prepare.md.txt b/v0.13.0/_sources/tracing/prepare.md.txt new file mode 100644 index 0000000000..98ceafe5d3 --- /dev/null +++ b/v0.13.0/_sources/tracing/prepare.md.txt @@ -0,0 +1,27 @@ +# Tracing `Session::prepare` + +`Session::prepare` prepares a query on all connections. If tracing is enabled for the `Query` to prepare, the resulting `PreparedStatement` will contain `prepare_tracing_ids`. `prepare_tracing_ids` is a list of tracing ids of prepare requests on all connections. + +```rust +use scylla::query::Query; +use scylla::prepared_statement::PreparedStatement; +use scylla::tracing::TracingInfo; +use uuid::Uuid; + +// Prepare the query with tracing enabled +let mut to_prepare: Query = Query::new("SELECT a FROM ks.tab"); +to_prepare.set_tracing(true); + +let mut prepared: PreparedStatement = session + .prepare(to_prepare) + .await?; + +// Now there are tracing ids for each prepare request +let tracing_ids: &[Uuid] = &prepared.prepare_tracing_ids; + +for id in tracing_ids { + // Query tracing info from system_traces.sessions and system_traces.events + let tracing_info: TracingInfo = session.get_tracing_info(id).await?; + println!("tracing_info: {:#?}", tracing_info); +} +``` diff --git a/v0.13.0/_sources/tracing/query-history.md.txt b/v0.13.0/_sources/tracing/query-history.md.txt new file mode 100644 index 0000000000..feb7c86be2 --- /dev/null +++ b/v0.13.0/_sources/tracing/query-history.md.txt @@ -0,0 +1,106 @@ +# Query Execution History + +The driver allows to collect history of query execution.\ +This history includes all requests sent, decisions to retry and speculative execution fibers started. + +## Example code + +```rust +use scylla::query::Query; +use scylla::history::{HistoryCollector, StructuredHistory}; +use std::sync::Arc; + +// Create a query for which we would like to trace the history of its execution +let mut query: Query = Query::new("SELECT * FROM ks.t"); + +// Create a history collector and pass it to the query +let history_listener = Arc::new(HistoryCollector::new()); +query.set_history_listener(history_listener.clone()); + +// Run the query, doesn't matter if it failed, the history will still be saved +let _ignore_error = session.query(query.clone(), ()).await; + +// Access the collected history and print it +let structured_history: StructuredHistory = history_listener.clone_structured_history(); +println!("Query history: {}", structured_history); +``` +To see more check out the [example code](https://github.com/scylladb/scylla-rust-driver/blob/main/examples/query_history.rs) + +## Output + +Sample output for a query that didn't encounter any difficulties: +```none +=== Query #0 === +| start_time: 2022-08-25 11:21:50.445075147 UTC +| Non-speculative attempts: +| - Attempt #0 sent to 127.0.0.1:9042 +| request send time: 2022-08-25 11:21:50.445151628 UTC +| Success at 2022-08-25 11:21:50.447444362 UTC +| +| Query successful at 2022-08-25 11:21:50.447447970 UTC +================= +``` + +Here's output for a query that had some trouble - nodes didn't respond and speculative execution decided to query others in parallel. +Finally the third node provided a response. +```none +=== Query #0 === +| start_time: 2022-08-26 15:08:28.525367409 UTC +| Non-speculative attempts: +| - Attempt #0 sent to 127.0.0.219:9042 +| request send time: 2022-08-26 15:08:28.525409294 UTC +| No result yet +| +| +| > Speculative fiber #0 +| fiber start time: 2022-08-26 15:08:28.537074167 UTC +| - Attempt #0 sent to 127.0.0.217:9042 +| request send time: 2022-08-26 15:08:28.537126083 UTC +| No result yet +| +| +| > Speculative fiber #1 +| fiber start time: 2022-08-26 15:08:28.548050242 UTC +| - Attempt #0 sent to 127.0.0.218:9042 +| request send time: 2022-08-26 15:08:28.548089083 UTC +| Success at 2022-08-26 15:08:28.590052778 UTC +| +| Query successful at 2022-08-26 15:08:28.590078119 UTC +================= +``` + +## How the driver executes queries + +To read the output it's useful to understand more about how the driver executes queries. + +### No speculative execution +Without speculative execution the driver performs many attempts sequentially until one of them succeeds. +A single attempt consists of sending a request to some node and waiting for the answer. +In case of an error the driver consults the retry policy to decide what to do next. +The decision might be to fail the query, retry on the same node, another node, change query parameters, etc. +Once the decision is made either the query fails or another attempt is started. This continues until the query ends. + +### Speculative execution +When speculative execution is enabled at first the driver doesn't care about it - it does the attempts sequentially and tries to get an answer. +However once a specified amount of time has passed it will decide to try new attempts in parallel +hoping that another node will be able to answer quicker. +This is done by spawning a speculative fiber. Each spawned fiber performs sequential attempts just like in non-speculative execution. +Many fibers can be spawned if the answer wasn't acquired in time. + +### StructuredHistory +[`StructuredHistory`](https://docs.rs/scylla/latest/scylla/history/struct.StructuredHistory.html) +is a history representation that represents the history by listing attempts for each speculative fiber. + +## HistoryListener trait, custom history collecting + +History can be collected by any struct implementing the +[`HistoryListener`](https://docs.rs/scylla/latest/scylla/history/trait.HistoryListener.html) trait. + +The implementation of `HistoryListener` provided by this crate is the +[`HistoryCollector`](https://docs.rs/scylla/latest/scylla/history/struct.HistoryCollector.html). +`HistoryCollector` simply collects all events along with their timestamps. + +Information collected by `HistoryCollector` is just a stream of events, in order to analyze it it's possible +to convert it to a structured representation. +[`StructuredHistory`](https://docs.rs/scylla/latest/scylla/history/struct.StructuredHistory.html) +can be created by calling `HistoryCollector::clone_structured_history()`. diff --git a/v0.13.0/_sources/tracing/tracing.md.txt b/v0.13.0/_sources/tracing/tracing.md.txt new file mode 100644 index 0000000000..75ea2d5fee --- /dev/null +++ b/v0.13.0/_sources/tracing/tracing.md.txt @@ -0,0 +1,41 @@ +# Query tracing + +The driver has utilities for monitoring the execution of queries. +There are two separate ways to get information about what happened with a query: `Tracing` and `Query Execution History`. + +### Tracing + +Tracing is a feature provided by Scylla. When sending a query we can set a flag that signifies that we would like it to be traced. +After completing the query Scylla provides a `tracing_id` which can be used to fetch information about it - which nodes it was sent to, what operations were performed etc. + +Queries that support tracing: +* [`Session::query()`](basic.md) +* [`Session::query_iter()`](paged.md) +* [`Session::execute()`](basic.md) +* [`Session::execute_iter()`](paged.md) +* [`Session::batch()`](basic.md) +* [`Session::prepare()`](prepare.md) + +After obtaining the tracing id you can use `Session::get_tracing_info()` to query tracing information.\ +`TracingInfo` contains values that are the same in Scylla and Cassandra®, skipping any database-specific ones.\ +If `TracingInfo` does not contain some needed value it's possible to query it manually from the tables +`system_traces.sessions` and `system_traces.events` + +### Query Execution History + +Tracing provides information about how the query execution went on database nodes, but it doesn't say anything about what was going on inside the driver.\ +This is what query execution history was made for. + +It allows to follow what the driver was thinking - all query attempts, retry decisions, speculative executions. +More information is available in the [Query Execution History](query-history.md) chapter. + +```{eval-rst} +.. toctree:: + :hidden: + :glob: + + basic + paged + prepare + query-history +``` \ No newline at end of file diff --git a/v0.13.0/_static/basic.css b/v0.13.0/_static/basic.css new file mode 100644 index 0000000000..30fee9d0f7 --- /dev/null +++ b/v0.13.0/_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/v0.13.0/_static/check-solid.svg b/v0.13.0/_static/check-solid.svg new file mode 100644 index 0000000000..92fad4b5c0 --- /dev/null +++ b/v0.13.0/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v0.13.0/_static/clipboard.min.js b/v0.13.0/_static/clipboard.min.js new file mode 100644 index 0000000000..54b3c46381 --- /dev/null +++ b/v0.13.0/_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/v0.13.0/_static/copybutton.css b/v0.13.0/_static/copybutton.css new file mode 100644 index 0000000000..f1916ec7d1 --- /dev/null +++ b/v0.13.0/_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/v0.13.0/_static/copybutton.js b/v0.13.0/_static/copybutton.js new file mode 100644 index 0000000000..2ea7ff3e21 --- /dev/null +++ b/v0.13.0/_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/v0.13.0/_static/copybutton_funcs.js b/v0.13.0/_static/copybutton_funcs.js new file mode 100644 index 0000000000..dbe1aaad79 --- /dev/null +++ b/v0.13.0/_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/v0.13.0/_static/css/main.css b/v0.13.0/_static/css/main.css new file mode 100644 index 0000000000..65eb0a5536 --- /dev/null +++ b/v0.13.0/_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/v0.13.0/_static/doctools.js b/v0.13.0/_static/doctools.js new file mode 100644 index 0000000000..d06a71d751 --- /dev/null +++ b/v0.13.0/_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/v0.13.0/_static/documentation_options.js b/v0.13.0/_static/documentation_options.js new file mode 100644 index 0000000000..7e4c114f21 --- /dev/null +++ b/v0.13.0/_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/v0.13.0/_static/file.png b/v0.13.0/_static/file.png new file mode 100644 index 0000000000..a858a410e4 Binary files /dev/null and b/v0.13.0/_static/file.png differ diff --git a/v0.13.0/_static/img/banner-background.svg b/v0.13.0/_static/img/banner-background.svg new file mode 100644 index 0000000000..f8520d5b3e --- /dev/null +++ b/v0.13.0/_static/img/banner-background.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v0.13.0/_static/img/favicon-228x228.png b/v0.13.0/_static/img/favicon-228x228.png new file mode 100644 index 0000000000..f30770c7ed Binary files /dev/null and b/v0.13.0/_static/img/favicon-228x228.png differ diff --git a/v0.13.0/_static/img/favicon-32x32.png b/v0.13.0/_static/img/favicon-32x32.png new file mode 100644 index 0000000000..aae1708f26 Binary files /dev/null and b/v0.13.0/_static/img/favicon-32x32.png differ diff --git a/v0.13.0/_static/img/favicon.ico b/v0.13.0/_static/img/favicon.ico new file mode 100644 index 0000000000..6c7484f082 Binary files /dev/null and b/v0.13.0/_static/img/favicon.ico differ diff --git a/v0.13.0/_static/img/icons/icon-about-team.svg b/v0.13.0/_static/img/icons/icon-about-team.svg new file mode 100644 index 0000000000..5448c7f007 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-about-team.svg @@ -0,0 +1 @@ +icon-about-team diff --git a/v0.13.0/_static/img/icons/icon-about-us-m.svg b/v0.13.0/_static/img/icons/icon-about-us-m.svg new file mode 100644 index 0000000000..09107d9520 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-about-us-m.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.13.0/_static/img/icons/icon-about-us.svg b/v0.13.0/_static/img/icons/icon-about-us.svg new file mode 100644 index 0000000000..1b1fcc83e3 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-about-us.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.13.0/_static/img/icons/icon-alternator.svg b/v0.13.0/_static/img/icons/icon-alternator.svg new file mode 100644 index 0000000000..7c2b4ebae0 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-alternator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.13.0/_static/img/icons/icon-apps.svg b/v0.13.0/_static/img/icons/icon-apps.svg new file mode 100644 index 0000000000..7e93612026 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-apps.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-architecture.svg b/v0.13.0/_static/img/icons/icon-architecture.svg new file mode 100644 index 0000000000..67ebbc2f38 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-architecture.svg @@ -0,0 +1 @@ +icon-architecture diff --git a/v0.13.0/_static/img/icons/icon-benchmarks.svg b/v0.13.0/_static/img/icons/icon-benchmarks.svg new file mode 100644 index 0000000000..e1ce2c1d78 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-benchmarks.svg @@ -0,0 +1 @@ +icon-benchmarks diff --git a/v0.13.0/_static/img/icons/icon-blog.svg b/v0.13.0/_static/img/icons/icon-blog.svg new file mode 100644 index 0000000000..f4096cbf11 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-blog.svg @@ -0,0 +1 @@ +icon-blog2 diff --git a/v0.13.0/_static/img/icons/icon-careers.svg b/v0.13.0/_static/img/icons/icon-careers.svg new file mode 100644 index 0000000000..2a7c6ea0b7 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-careers.svg @@ -0,0 +1 @@ +icon-careers diff --git a/v0.13.0/_static/img/icons/icon-chevron-left.svg b/v0.13.0/_static/img/icons/icon-chevron-left.svg new file mode 100644 index 0000000000..3afa25c481 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-chevron-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/v0.13.0/_static/img/icons/icon-chevron-right.svg b/v0.13.0/_static/img/icons/icon-chevron-right.svg new file mode 100644 index 0000000000..44eb829cdc --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/v0.13.0/_static/img/icons/icon-circe.svg b/v0.13.0/_static/img/icons/icon-circe.svg new file mode 100644 index 0000000000..875e421670 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-circe.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-clock.svg b/v0.13.0/_static/img/icons/icon-clock.svg new file mode 100644 index 0000000000..8c92469808 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-clock.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-close.svg b/v0.13.0/_static/img/icons/icon-close.svg new file mode 100644 index 0000000000..d1162b73e7 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-close.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/v0.13.0/_static/img/icons/icon-cloud-docs.svg b/v0.13.0/_static/img/icons/icon-cloud-docs.svg new file mode 100644 index 0000000000..a9069bb6e5 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-cloud-docs.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-cloud.svg b/v0.13.0/_static/img/icons/icon-cloud.svg new file mode 100644 index 0000000000..cfb2318dae --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.13.0/_static/img/icons/icon-comparison.svg b/v0.13.0/_static/img/icons/icon-comparison.svg new file mode 100644 index 0000000000..49d809a5df --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-comparison.svg @@ -0,0 +1 @@ +icon-comparison diff --git a/v0.13.0/_static/img/icons/icon-contact-us.svg b/v0.13.0/_static/img/icons/icon-contact-us.svg new file mode 100644 index 0000000000..9df3145dd2 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-contact-us.svg @@ -0,0 +1 @@ +icon-contact-us diff --git a/v0.13.0/_static/img/icons/icon-developers-blog.svg b/v0.13.0/_static/img/icons/icon-developers-blog.svg new file mode 100644 index 0000000000..ee804197a0 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-developers-blog.svg @@ -0,0 +1 @@ +icon-developers-blog diff --git a/v0.13.0/_static/img/icons/icon-docs.svg b/v0.13.0/_static/img/icons/icon-docs.svg new file mode 100644 index 0000000000..5501492f3e --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-docs.svg @@ -0,0 +1 @@ +icon-docs diff --git a/v0.13.0/_static/img/icons/icon-enterprise-m.svg b/v0.13.0/_static/img/icons/icon-enterprise-m.svg new file mode 100644 index 0000000000..97be900b50 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-enterprise-m.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.13.0/_static/img/icons/icon-enterprise.svg b/v0.13.0/_static/img/icons/icon-enterprise.svg new file mode 100644 index 0000000000..ee1ac26283 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.13.0/_static/img/icons/icon-events.svg b/v0.13.0/_static/img/icons/icon-events.svg new file mode 100644 index 0000000000..ba5f211864 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-events.svg @@ -0,0 +1 @@ +icon-events diff --git a/v0.13.0/_static/img/icons/icon-exclamation.svg b/v0.13.0/_static/img/icons/icon-exclamation.svg new file mode 100644 index 0000000000..a7eb4b77a4 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-exclamation.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v0.13.0/_static/img/icons/icon-expand.svg b/v0.13.0/_static/img/icons/icon-expand.svg new file mode 100644 index 0000000000..3806565367 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-expand.svg @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/v0.13.0/_static/img/icons/icon-forum.svg b/v0.13.0/_static/img/icons/icon-forum.svg new file mode 100644 index 0000000000..37a709f7a8 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-forum.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-getting-started.svg b/v0.13.0/_static/img/icons/icon-getting-started.svg new file mode 100644 index 0000000000..702500be40 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-getting-started.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-glossary.svg b/v0.13.0/_static/img/icons/icon-glossary.svg new file mode 100644 index 0000000000..e8329c2afe --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-glossary.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-home.svg b/v0.13.0/_static/img/icons/icon-home.svg new file mode 100644 index 0000000000..f0b9c25419 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-home.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-infoworld.svg b/v0.13.0/_static/img/icons/icon-infoworld.svg new file mode 100644 index 0000000000..906e87279c --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-infoworld.svg @@ -0,0 +1 @@ +icon-infoworld diff --git a/v0.13.0/_static/img/icons/icon-integrations.svg b/v0.13.0/_static/img/icons/icon-integrations.svg new file mode 100644 index 0000000000..1ef0920d49 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-integrations.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-knowledge-base.svg b/v0.13.0/_static/img/icons/icon-knowledge-base.svg new file mode 100644 index 0000000000..884451270d --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-knowledge-base.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-less.svg b/v0.13.0/_static/img/icons/icon-less.svg new file mode 100644 index 0000000000..3094127dec --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-less.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v0.13.0/_static/img/icons/icon-live-test.svg b/v0.13.0/_static/img/icons/icon-live-test.svg new file mode 100644 index 0000000000..dcb5916c26 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-live-test.svg @@ -0,0 +1 @@ +icon-live-test diff --git a/v0.13.0/_static/img/icons/icon-mail-list.svg b/v0.13.0/_static/img/icons/icon-mail-list.svg new file mode 100644 index 0000000000..0e6192a352 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-mail-list.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-manager.svg b/v0.13.0/_static/img/icons/icon-manager.svg new file mode 100644 index 0000000000..02b4e425be --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-manager.svg @@ -0,0 +1 @@ +icon-manager diff --git a/v0.13.0/_static/img/icons/icon-memory-management.svg b/v0.13.0/_static/img/icons/icon-memory-management.svg new file mode 100644 index 0000000000..e34eb4504f --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-memory-management.svg @@ -0,0 +1 @@ +icon-memory-management diff --git a/v0.13.0/_static/img/icons/icon-modeling.svg b/v0.13.0/_static/img/icons/icon-modeling.svg new file mode 100644 index 0000000000..97fa3a0e21 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-modeling.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-monitoring.svg b/v0.13.0/_static/img/icons/icon-monitoring.svg new file mode 100644 index 0000000000..80b3787f66 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-monitoring.svg @@ -0,0 +1 @@ +icon-monitoring diff --git a/v0.13.0/_static/img/icons/icon-networking.svg b/v0.13.0/_static/img/icons/icon-networking.svg new file mode 100644 index 0000000000..40a3fd5f6f --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-networking.svg @@ -0,0 +1 @@ +icon-networking diff --git a/v0.13.0/_static/img/icons/icon-news.svg b/v0.13.0/_static/img/icons/icon-news.svg new file mode 100644 index 0000000000..a952b59937 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-news.svg @@ -0,0 +1 @@ +icon-news diff --git a/v0.13.0/_static/img/icons/icon-newsletter.svg b/v0.13.0/_static/img/icons/icon-newsletter.svg new file mode 100644 index 0000000000..5b8d47eb15 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-newsletter.svg @@ -0,0 +1 @@ +icon-newsletter diff --git a/v0.13.0/_static/img/icons/icon-nsql-guides.svg b/v0.13.0/_static/img/icons/icon-nsql-guides.svg new file mode 100644 index 0000000000..60ebab3795 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-nsql-guides.svg @@ -0,0 +1 @@ +icon-nsql-guides diff --git a/v0.13.0/_static/img/icons/icon-open-source.svg b/v0.13.0/_static/img/icons/icon-open-source.svg new file mode 100644 index 0000000000..98c2ea7d5b --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-open-source.svg @@ -0,0 +1 @@ +icon-open-source diff --git a/v0.13.0/_static/img/icons/icon-operator.svg b/v0.13.0/_static/img/icons/icon-operator.svg new file mode 100644 index 0000000000..bb7d8d3ea8 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-operator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.13.0/_static/img/icons/icon-overview.svg b/v0.13.0/_static/img/icons/icon-overview.svg new file mode 100644 index 0000000000..515c1528a2 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-overview.svg @@ -0,0 +1 @@ +icon-overview diff --git a/v0.13.0/_static/img/icons/icon-partners.svg b/v0.13.0/_static/img/icons/icon-partners.svg new file mode 100644 index 0000000000..d0146fc497 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-partners.svg @@ -0,0 +1 @@ +icon-partners diff --git a/v0.13.0/_static/img/icons/icon-plus.svg b/v0.13.0/_static/img/icons/icon-plus.svg new file mode 100644 index 0000000000..5757435085 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-plus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/v0.13.0/_static/img/icons/icon-pricing.svg b/v0.13.0/_static/img/icons/icon-pricing.svg new file mode 100644 index 0000000000..74b01db168 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-pricing.svg @@ -0,0 +1 @@ +icon-pricing$ diff --git a/v0.13.0/_static/img/icons/icon-release-notes.svg b/v0.13.0/_static/img/icons/icon-release-notes.svg new file mode 100644 index 0000000000..80c490c7b0 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-release-notes.svg @@ -0,0 +1 @@ +icon-release-notes diff --git a/v0.13.0/_static/img/icons/icon-resource-center.svg b/v0.13.0/_static/img/icons/icon-resource-center.svg new file mode 100644 index 0000000000..6e3ab08e79 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-resource-center.svg @@ -0,0 +1 @@ +icon-ressource-center diff --git a/v0.13.0/_static/img/icons/icon-roadmap.svg b/v0.13.0/_static/img/icons/icon-roadmap.svg new file mode 100644 index 0000000000..c8cbf67c8c --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-roadmap.svg @@ -0,0 +1 @@ +icon-roadmap-4 diff --git a/v0.13.0/_static/img/icons/icon-search.svg b/v0.13.0/_static/img/icons/icon-search.svg new file mode 100644 index 0000000000..81aae93eef --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v0.13.0/_static/img/icons/icon-slack.svg b/v0.13.0/_static/img/icons/icon-slack.svg new file mode 100644 index 0000000000..fc164ea1e7 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-slack.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-stack-overflow.svg b/v0.13.0/_static/img/icons/icon-stack-overflow.svg new file mode 100644 index 0000000000..bebe9b8274 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/v0.13.0/_static/img/icons/icon-summit.svg b/v0.13.0/_static/img/icons/icon-summit.svg new file mode 100644 index 0000000000..4b900bd0c0 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-summit.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/icons/icon-support.svg b/v0.13.0/_static/img/icons/icon-support.svg new file mode 100644 index 0000000000..a4228b34e8 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-support.svg @@ -0,0 +1 @@ +icon-support diff --git a/v0.13.0/_static/img/icons/icon-tech-talks.svg b/v0.13.0/_static/img/icons/icon-tech-talks.svg new file mode 100644 index 0000000000..df42b5522b --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-tech-talks.svg @@ -0,0 +1 @@ +icon-tech-talks diff --git a/v0.13.0/_static/img/icons/icon-testing.svg b/v0.13.0/_static/img/icons/icon-testing.svg new file mode 100644 index 0000000000..2fe54efdbc --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-testing.svg @@ -0,0 +1 @@ +icon-testing diff --git a/v0.13.0/_static/img/icons/icon-thumbs-down.svg b/v0.13.0/_static/img/icons/icon-thumbs-down.svg new file mode 100644 index 0000000000..3e7bcd6d90 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.13.0/_static/img/icons/icon-thumbs-up.svg b/v0.13.0/_static/img/icons/icon-thumbs-up.svg new file mode 100644 index 0000000000..226c44d853 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-thumbs-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v0.13.0/_static/img/icons/icon-tip.svg b/v0.13.0/_static/img/icons/icon-tip.svg new file mode 100644 index 0000000000..bf7aa6af84 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-tip.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/v0.13.0/_static/img/icons/icon-training.svg b/v0.13.0/_static/img/icons/icon-training.svg new file mode 100644 index 0000000000..08b95a88ed --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-training.svg @@ -0,0 +1 @@ +icon-training diff --git a/v0.13.0/_static/img/icons/icon-triangle-down.svg b/v0.13.0/_static/img/icons/icon-triangle-down.svg new file mode 100644 index 0000000000..e8ae088106 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-triangle-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/v0.13.0/_static/img/icons/icon-university.svg b/v0.13.0/_static/img/icons/icon-university.svg new file mode 100644 index 0000000000..f7547ab959 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-university.svg @@ -0,0 +1 @@ +icon-university diff --git a/v0.13.0/_static/img/icons/icon-users-blog.svg b/v0.13.0/_static/img/icons/icon-users-blog.svg new file mode 100644 index 0000000000..47e56cddcf --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-users-blog.svg @@ -0,0 +1 @@ +icon-users-blog diff --git a/v0.13.0/_static/img/icons/icon-warning.svg b/v0.13.0/_static/img/icons/icon-warning.svg new file mode 100644 index 0000000000..e4b1d40331 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-warning.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/v0.13.0/_static/img/icons/icon-webinars.svg b/v0.13.0/_static/img/icons/icon-webinars.svg new file mode 100644 index 0000000000..5e9f5cd427 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-webinars.svg @@ -0,0 +1 @@ +icon-webinars diff --git a/v0.13.0/_static/img/icons/icon-whitepapers.svg b/v0.13.0/_static/img/icons/icon-whitepapers.svg new file mode 100644 index 0000000000..3351e51d23 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-whitepapers.svg @@ -0,0 +1 @@ +icon-whitepapers diff --git a/v0.13.0/_static/img/icons/icon-workshop.svg b/v0.13.0/_static/img/icons/icon-workshop.svg new file mode 100644 index 0000000000..5206e58e98 --- /dev/null +++ b/v0.13.0/_static/img/icons/icon-workshop.svg @@ -0,0 +1 @@ + diff --git a/v0.13.0/_static/img/logo-docs.svg b/v0.13.0/_static/img/logo-docs.svg new file mode 100644 index 0000000000..4fff669cb6 --- /dev/null +++ b/v0.13.0/_static/img/logo-docs.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.13.0/_static/img/logo-scylla-horizontal-RGB.svg b/v0.13.0/_static/img/logo-scylla-horizontal-RGB.svg new file mode 100644 index 0000000000..b5022d7c4d --- /dev/null +++ b/v0.13.0/_static/img/logo-scylla-horizontal-RGB.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/v0.13.0/_static/img/mascots/404.jpg b/v0.13.0/_static/img/mascots/404.jpg new file mode 100644 index 0000000000..769fa0889f Binary files /dev/null and b/v0.13.0/_static/img/mascots/404.jpg differ diff --git a/v0.13.0/_static/img/mascots/scylla-3monsters.png b/v0.13.0/_static/img/mascots/scylla-3monsters.png new file mode 100644 index 0000000000..7c06d01674 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-3monsters.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-advisor-crystal.png b/v0.13.0/_static/img/mascots/scylla-advisor-crystal.png new file mode 100644 index 0000000000..d33fddd62f Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-advisor-crystal.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-alternator.svg b/v0.13.0/_static/img/mascots/scylla-alternator.svg new file mode 100644 index 0000000000..0462f893d5 --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-alternator.svg @@ -0,0 +1 @@ +scylla-alternator diff --git a/v0.13.0/_static/img/mascots/scylla-cloud.svg b/v0.13.0/_static/img/mascots/scylla-cloud.svg new file mode 100644 index 0000000000..a6c6a26fc9 --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-cloud.svg @@ -0,0 +1 @@ +scylla-cloud diff --git a/v0.13.0/_static/img/mascots/scylla-computer-3-monsters.png b/v0.13.0/_static/img/mascots/scylla-computer-3-monsters.png new file mode 100644 index 0000000000..d0368a7027 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-computer-3-monsters.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-computer-headset.png b/v0.13.0/_static/img/mascots/scylla-computer-headset.png new file mode 100644 index 0000000000..0cdadaa216 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-computer-headset.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-cup-number-one.png b/v0.13.0/_static/img/mascots/scylla-cup-number-one.png new file mode 100644 index 0000000000..e889f4e368 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-cup-number-one.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-docs.svg b/v0.13.0/_static/img/mascots/scylla-docs.svg new file mode 100644 index 0000000000..a5bce950c2 --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-docs.svg @@ -0,0 +1 @@ +scylla-docs diff --git a/v0.13.0/_static/img/mascots/scylla-drivers.svg b/v0.13.0/_static/img/mascots/scylla-drivers.svg new file mode 100644 index 0000000000..6012e71679 --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-drivers.svg @@ -0,0 +1 @@ +scylla-manager diff --git a/v0.13.0/_static/img/mascots/scylla-enterprise.svg b/v0.13.0/_static/img/mascots/scylla-enterprise.svg new file mode 100644 index 0000000000..a1aa0b46ac --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-enterprise.svg @@ -0,0 +1 @@ +scylla-enterprise diff --git a/v0.13.0/_static/img/mascots/scylla-forklift-boxes.png b/v0.13.0/_static/img/mascots/scylla-forklift-boxes.png new file mode 100644 index 0000000000..f64c29e6c7 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-forklift-boxes.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-forklift-migration.png b/v0.13.0/_static/img/mascots/scylla-forklift-migration.png new file mode 100644 index 0000000000..d2f645c645 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-forklift-migration.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-gear.png b/v0.13.0/_static/img/mascots/scylla-gear.png new file mode 100644 index 0000000000..0f53b26afa Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-gear.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-hardhat.png b/v0.13.0/_static/img/mascots/scylla-hardhat.png new file mode 100644 index 0000000000..630f2d9094 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-hardhat.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-headband.png b/v0.13.0/_static/img/mascots/scylla-headband.png new file mode 100644 index 0000000000..c87abe684d Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-headband.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-headset.png b/v0.13.0/_static/img/mascots/scylla-headset.png new file mode 100644 index 0000000000..ba52cd223d Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-headset.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-hearts.png b/v0.13.0/_static/img/mascots/scylla-hearts.png new file mode 100644 index 0000000000..cef08c8654 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-hearts.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-looking-down.png b/v0.13.0/_static/img/mascots/scylla-looking-down.png new file mode 100644 index 0000000000..75cccbfdf1 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-looking-down.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-looking-up.png b/v0.13.0/_static/img/mascots/scylla-looking-up.png new file mode 100644 index 0000000000..6f10405f21 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-looking-up.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-magnifying-glass-fronting.png b/v0.13.0/_static/img/mascots/scylla-magnifying-glass-fronting.png new file mode 100644 index 0000000000..e368cae169 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-magnifying-glass-fronting.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-magnifying-glass.png b/v0.13.0/_static/img/mascots/scylla-magnifying-glass.png new file mode 100644 index 0000000000..74ad669500 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-magnifying-glass.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-manager.svg b/v0.13.0/_static/img/mascots/scylla-manager.svg new file mode 100644 index 0000000000..6ba9ed937c --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-manager.svg @@ -0,0 +1 @@ +scylla-manager-2 diff --git a/v0.13.0/_static/img/mascots/scylla-monitor.svg b/v0.13.0/_static/img/mascots/scylla-monitor.svg new file mode 100644 index 0000000000..48bec7dde3 --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-monitor.svg @@ -0,0 +1 @@ +scylla-monitor diff --git a/v0.13.0/_static/img/mascots/scylla-movement-fast.png b/v0.13.0/_static/img/mascots/scylla-movement-fast.png new file mode 100644 index 0000000000..956d1dd0e2 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-movement-fast.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-movement.png b/v0.13.0/_static/img/mascots/scylla-movement.png new file mode 100644 index 0000000000..7ee2b04338 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-movement.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-onpremise.png b/v0.13.0/_static/img/mascots/scylla-onpremise.png new file mode 100644 index 0000000000..3b2dc8f1a2 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-onpremise.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-opensource.svg b/v0.13.0/_static/img/mascots/scylla-opensource.svg new file mode 100644 index 0000000000..299e9cb995 --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-opensource.svg @@ -0,0 +1 @@ +Plan de travail 1 diff --git a/v0.13.0/_static/img/mascots/scylla-operator.svg b/v0.13.0/_static/img/mascots/scylla-operator.svg new file mode 100644 index 0000000000..655a450b2a --- /dev/null +++ b/v0.13.0/_static/img/mascots/scylla-operator.svg @@ -0,0 +1 @@ +scylla-operator diff --git a/v0.13.0/_static/img/mascots/scylla-plugin.png b/v0.13.0/_static/img/mascots/scylla-plugin.png new file mode 100644 index 0000000000..b28dc857cc Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-plugin.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-release-mascot.png b/v0.13.0/_static/img/mascots/scylla-release-mascot.png new file mode 100644 index 0000000000..09342ac687 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-release-mascot.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-repair.png b/v0.13.0/_static/img/mascots/scylla-repair.png new file mode 100644 index 0000000000..9b4c613e70 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-repair.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-server.png b/v0.13.0/_static/img/mascots/scylla-server.png new file mode 100644 index 0000000000..96dc785298 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-server.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-sleeping.png b/v0.13.0/_static/img/mascots/scylla-sleeping.png new file mode 100644 index 0000000000..f88598e05a Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-sleeping.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-tall-measure.png b/v0.13.0/_static/img/mascots/scylla-tall-measure.png new file mode 100644 index 0000000000..6f0ca146c0 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-tall-measure.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-university.png b/v0.13.0/_static/img/mascots/scylla-university.png new file mode 100644 index 0000000000..b3d0621193 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-university.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-weights.png b/v0.13.0/_static/img/mascots/scylla-weights.png new file mode 100644 index 0000000000..b070bb022c Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-weights.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-window-cleaning.png b/v0.13.0/_static/img/mascots/scylla-window-cleaning.png new file mode 100644 index 0000000000..6a8b16a6b4 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-window-cleaning.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-with-computer-2.png b/v0.13.0/_static/img/mascots/scylla-with-computer-2.png new file mode 100644 index 0000000000..f3b8b2984f Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-with-computer-2.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-with-computer.png b/v0.13.0/_static/img/mascots/scylla-with-computer.png new file mode 100644 index 0000000000..b38a6fbbe0 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-with-computer.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-with-linux.png b/v0.13.0/_static/img/mascots/scylla-with-linux.png new file mode 100644 index 0000000000..954bf13bc2 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-with-linux.png differ diff --git a/v0.13.0/_static/img/mascots/scylla-writting.png b/v0.13.0/_static/img/mascots/scylla-writting.png new file mode 100644 index 0000000000..d35a13d380 Binary files /dev/null and b/v0.13.0/_static/img/mascots/scylla-writting.png differ diff --git a/v0.13.0/_static/img/menu.svg b/v0.13.0/_static/img/menu.svg new file mode 100644 index 0000000000..30ea1d901e --- /dev/null +++ b/v0.13.0/_static/img/menu.svg @@ -0,0 +1,3 @@ + + + diff --git a/v0.13.0/_static/js/main.bundle.js b/v0.13.0/_static/js/main.bundle.js new file mode 100644 index 0000000000..190a41642e --- /dev/null +++ b/v0.13.0/_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 +
            +
            +
            +
            +
            + + + + + + +
            +

            Authentication

            +

            Driver supports both authentication by username and password and custom authentication defined by a user.

            + +
            +

            Custom Authentication

            +

            A custom authentication is defined by implementing the AuthenticatorSession. +An AuthenticatorSession instance is created per session, so it is also necessary to define a AuthenticatorProvider for it. +Finally, to make use of the custom authentication, use the authenticator_provider method in SessionBuilder:

            +
            use bytes::{BufMut, BytesMut};
            +use async_trait::async_trait;
            +use scylla::authentication::{AuthError, AuthenticatorProvider, AuthenticatorSession};
            +
            +struct CustomAuthenticator;
            +
            +#[async_trait]
            +impl AuthenticatorSession for CustomAuthenticator {
            +    // to handle an authentication challenge initiated by the server.
            +    // The information contained in the token parameter is authentication protocol specific.
            +    // It may be NULL or empty. 
            +    async fn evaluate_challenge(
            +        &mut self,
            +        _token: Option<&[u8]>,
            +    ) -> Result<Option<Vec<u8>>, AuthError> {
            +        Err("Challenges are not expected".to_string())
            +    }
            +
            +    // to handle the success phase of exchange. The token parameters contain information that may be used to finalize the request.
            +    async fn success(&mut self, _token: Option<&[u8]>) -> Result<(), AuthError> {
            +        Ok(())
            +    }
            +}
            +
            +struct CustomAuthenticatorProvider;
            +
            +#[async_trait]
            +impl AuthenticatorProvider for CustomAuthenticatorProvider {
            +    async fn start_authentication_session(
            +        &self,
            +        _name: &str,
            +    ) -> Result<(Option<Vec<u8>>, Box<dyn AuthenticatorSession>), AuthError> {
            +        let mut response = BytesMut::new();
            +        let cred = "\0cassandra\0cassandra";
            +        let cred_length = 20;
            +
            +        response.put_i32(cred_length);
            +        response.put_slice(cred.as_bytes());
            +
            +        Ok((Some(response.to_vec()), Box::new(CustomAuthenticator)))
            +    }
            +}
            +
            +async fn authentication_example() -> Result<(), Box<dyn Error>> {
            +    use scylla::{Session, SessionBuilder};
            +
            +    let _session: Session = SessionBuilder::new()
            +        .known_node("127.0.0.1:9042")
            +        .authenticator_provider(Arc::new(CustomAuthenticatorProvider))
            +        .build()
            +        .await?;
            +
            +    Ok(())
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/connecting/compression.html b/v0.13.0/connecting/compression.html new file mode 100644 index 0000000000..f32a0e8f9e --- /dev/null +++ b/v0.13.0/connecting/compression.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Compression | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Compression

            +

            By default the driver does not use any compression on connections.
            +It’s possible to specify a preferred compression algorithm.
            +The driver will try using it, but if the database doesn’t support it, it will fall back to no compression.

            +

            Available compression algorithms:

            +
              +
            • Snappy

            • +
            • LZ4

            • +
            +

            An example enabling Snappy compression algorithm:

            +
            use scylla::{Session, SessionBuilder};
            +use scylla::transport::Compression;
            +use std::error::Error;
            +
            +#[tokio::main]
            +async fn main() -> Result<(), Box<dyn Error>> {
            +    let uri = std::env::var("SCYLLA_URI")
            +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
            +
            +    let session: Session = SessionBuilder::new()
            +        .known_node(uri)
            +        .compression(Some(Compression::Snappy))
            +        .build()
            +        .await?;
            +
            +    Ok(())
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/connecting/connecting.html b/v0.13.0/connecting/connecting.html new file mode 100644 index 0000000000..ff832e85a5 --- /dev/null +++ b/v0.13.0/connecting/connecting.html @@ -0,0 +1,709 @@ + + + + + + + + + + + + + Connecting to the cluster | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Connecting to the cluster

            +

            Scylla is a distributed database, which means that it operates on multiple nodes running independently. +When creating a Session you can specify a few known nodes to which the driver will try connecting:

            +
            use scylla::{Session, SessionBuilder};
            +use std::error::Error;
            +use std::time::Duration;
            +use std::net::{IpAddr, Ipv4Addr, SocketAddr};
            +
            +#[tokio::main]
            +async fn main() -> Result<(), Box<dyn Error>> {
            +    let uri = std::env::var("SCYLLA_URI")
            +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
            +
            +    let session: Session = SessionBuilder::new()
            +        .known_node(uri)
            +        .known_node("127.0.0.72:4321")
            +        .known_node("localhost:8000")
            +        .connection_timeout(Duration::from_secs(3))
            +        .cluster_metadata_refresh_interval(Duration::from_secs(10))
            +        .known_node_addr(SocketAddr::new(
            +            IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
            +            9000,
            +        ))
            +        .build()
            +        .await?;
            +
            +    Ok(())
            +}
            +
            +
            +

            After successfully connecting to some specified node the driver will fetch topology information about +other nodes in this cluster and connect to them as well.

            +
            +

            Best practices for using Session

            +
            +

            Warning

            +

            Always try to use only a single Session object per apllication because creating them is very expensive!

            +
            +

            The driver maintains its own pool of connections to each node and each connection is capable of handling multiple requests in parallel. Driver will also route requests to nodes / shards that actually own the data (unless the load balancing policy that you use doesn’t support it).

            +

            For those reasons, we recommend using one instance of Session per application.

            +

            Creating short-lived Session’s (e.g. Session per request) is strongly discouraged because it will result in great performance penalties because creating a Session is a costly process - it requires estabilishing a lot of TCP connections. +Creating many Session’s in one application (e.g. Session per thread / per Tokio task) is also discouraged, because it wastes resources - as mentioned before, Session maintains a connection pool itself and can handle parallel queries, so you would be holding a lot of connections unnecessarily.

            +

            If you need to share Session with different threads / Tokio tasks etc. use Arc<Session> - all methods of Session take &self, so it doesn’t hinder the functionality in any way.

            +
            +
            +

            Metadata

            +

            The driver refreshes the cluster metadata periodically, which contains information about cluster topology as well as the cluster schema. By default, the driver refreshes the cluster metadata every 60 seconds. +However, you can set the cluster_metadata_refresh_interval to a non-negative value to periodically refresh the cluster metadata. This is useful when you do not have unexpected amount of traffic or when you have an extra traffic causing topology to change frequently.

            +
            +
            +

            Scylla Cloud Serverless

            +

            Scylla Serverless is an elastic and dynamic deployment model. When creating a Session you need to +specify the secure connection bundle as follows:

            +
            use std::path::Path;
            +use std::error::Error;
            +use scylla::CloudSessionBuilder;
            +
            +#[tokio::main]
            +async fn main() -> Result<(), Box<dyn Error>> {
            +    let session = CloudSessionBuilder::new(Path::new("config_data.yaml"))
            +        .unwrap()
            +        .build()
            +        .await
            +        .unwrap();
            +
            +    Ok(())
            +}
            +
            +
            +

            Note that the bundle file will be provided after the serverless cluster is created. Here is an example of a +configuration file for a serverless cluster:

            +
            datacenters:
            +  datacenter1:
            +    certificateAuthorityData: CERTIFICATE_DATA
            +    server: 127.0.1.1:9142
            +    nodeDomain: cql.cluster-id.scylla.com
            +    insecureSkipTlsVerify: false
            +authInfos:
            +  default:
            +    clientCertificateData: CERTIFICATE_DATA
            +    clientKeyData: KEY_DATA
            +    username: scylladb
            +    password: scylladb
            +contexts:
            +  default:
            +    datacenterName: datacenter1
            +    authInfoName: default
            +currentContext: default
            +
            +
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/connecting/tls.html b/v0.13.0/connecting/tls.html new file mode 100644 index 0000000000..37c35b1eef --- /dev/null +++ b/v0.13.0/connecting/tls.html @@ -0,0 +1,686 @@ + + + + + + + + + + + + + TLS | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            TLS

            +

            Driver uses the openssl crate for TLS functionality.
            +It was chosen because rustls doesn’t support certificates for ip addresses +(see issue), which is a common use case for Scylla.

            +
            +

            Enabling feature

            +

            openssl is not a pure Rust library so you need enable a feature and install the proper package.

            +

            To enable the tls feature add in Cargo.toml:

            +
            scylla = { version = "0.4", features = ["ssl"] }
            +openssl = "0.10.32"
            +
            +
            +

            Then install the package with openssl:

            +
              +
            • Debian/Ubuntu:

              +
              apt install libssl-dev pkg-config
              +
              +
              +
            • +
            • Fedora:

              +
              dnf install openssl-devel
              +
              +
              +
            • +
            + +
              +
            • Arch:

              +
              pacman -S openssl pkg-config
              +
              +
              +
            • +
            +
            +
            +

            Using TLS

            +

            To use tls you will have to create an openssl +SslContext +and pass it to SessionBuilder

            +

            For example, if database certificate is in the file ca.crt:

            +
            use scylla::{Session, SessionBuilder};
            +use openssl::ssl::{SslContextBuilder, SslMethod, SslVerifyMode};
            +use std::path::PathBuf;
            +
            +let mut context_builder = SslContextBuilder::new(SslMethod::tls())?;
            +context_builder.set_ca_file("ca.crt")?;
            +context_builder.set_verify(SslVerifyMode::PEER);
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9142") // The the port is now 9142
            +    .ssl_context(Some(context_builder.build()))
            +    .build()
            +    .await?;
            +
            +
            +

            See the full example for more details

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/contents.html b/v0.13.0/contents.html new file mode 100644 index 0000000000..26abbcb835 --- /dev/null +++ b/v0.13.0/contents.html @@ -0,0 +1,599 @@ + + + + + + + + + + + + + <no title> | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/blob.html b/v0.13.0/data-types/blob.html new file mode 100644 index 0000000000..bca667d347 --- /dev/null +++ b/v0.13.0/data-types/blob.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + + Blob | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Blob

            +

            Blob is represented as Vec<u8>

            +
            use scylla::IntoTypedRows;
            +
            +// Insert some blob into the table as a Vec<u8>
            +// We can insert it by reference to not move the whole blob
            +let to_insert: Vec<u8> = vec![1, 2, 3, 4, 5];
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&to_insert,))
            +    .await?;
            +
            +// Read blobs from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(Vec<u8>,)>()?;
            +while let Some((blob_value,)) = iter.next().transpose()? {
            +    println!("{:?}", blob_value);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/collections.html b/v0.13.0/data-types/collections.html new file mode 100644 index 0000000000..e7a5f79860 --- /dev/null +++ b/v0.13.0/data-types/collections.html @@ -0,0 +1,739 @@ + + + + + + + + + + + + + List, Set, Map | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            List, Set, Map

            +
            +

            List

            +

            List is represented as Vec<T>

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a list of ints into the table
            +let my_list: Vec<i32> = vec![1, 2, 3, 4, 5];
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_list,))
            +    .await?;
            +
            +// Read a list of ints from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(Vec<i32>,)>()?;
            +while let Some((list_value,)) = iter.next().transpose()? {
            +    println!("{:?}", list_value);
            +}
            +
            +
            +
            +
            +

            Set

            +

            Set is represented as Vec<T>, HashSet<T> or BTreeSet<T>:

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a set of ints into the table
            +let my_set: Vec<i32> = vec![1, 2, 3, 4, 5];
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
            +    .await?;
            +
            +// Read a set of ints from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(Vec<i32>,)>()?;
            +while let Some((list_value,)) = iter.next().transpose()? {
            +    println!("{:?}", list_value);
            +}
            +
            +
            +
            use scylla::IntoTypedRows;
            +use std::collections::HashSet;
            +
            +// Insert a set of ints into the table
            +let my_set: HashSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
            +    .await?;
            +
            +// Read a set of ints from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(HashSet<i32>,)>()?;
            +while let Some((list_value,)) = iter.next().transpose()? {
            +    println!("{:?}", list_value);
            +}
            +
            +
            +
            use scylla::IntoTypedRows;
            +use std::collections::BTreeSet;
            +
            +// Insert a set of ints into the table
            +let my_set: BTreeSet<i32> = vec![1, 2, 3, 4, 5].into_iter().collect();
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_set,))
            +    .await?;
            +
            +// Read a set of ints from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(BTreeSet<i32>,)>()?;
            +while let Some((list_value,)) = iter.next().transpose()? {
            +    println!("{:?}", list_value);
            +}
            +
            +
            +
            +
            +

            Map

            +

            Map is represented as HashMap<K, V> or BTreeMap<K, V>

            +
            use scylla::IntoTypedRows;
            +use std::collections::HashMap;
            +
            +// Insert a map of text and int into the table
            +let mut my_map: HashMap<String, i32> = HashMap::new();
            +my_map.insert("abcd".to_string(), 16);
            +
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,))
            +    .await?;
            +
            +// Read a map from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(HashMap<String, i32>,)>()?;
            +while let Some((map_value,)) = iter.next().transpose()? {
            +    println!("{:?}", map_value);
            +}
            +
            +
            +
            use scylla::IntoTypedRows;
            +use std::collections::BTreeMap;
            +
            +// Insert a map of text and int into the table
            +let mut my_map: BTreeMap<String, i32> = BTreeMap::new();
            +my_map.insert("abcd".to_string(), 16);
            +
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (&my_map,))
            +    .await?;
            +
            +// Read a map from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(BTreeMap<String, i32>,)>()?;
            +while let Some((map_value,)) = iter.next().transpose()? {
            +    println!("{:?}", map_value);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/counter.html b/v0.13.0/data-types/counter.html new file mode 100644 index 0000000000..eea9f028bf --- /dev/null +++ b/v0.13.0/data-types/counter.html @@ -0,0 +1,624 @@ + + + + + + + + + + + + + Counter | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Counter

            +

            Counter is represented as struct Counter(pub i64)
            +Counter can’t be inserted, it can only be read or updated.

            +
            use scylla::IntoTypedRows;
            +use scylla::frame::value::Counter;
            +
            +// Read counter from the table
            +let result = session.query("SELECT c FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(Counter,)>()?;
            +while let Some((counter_value,)) = iter.next().transpose()? {
            +    let counter_int_value: i64 = counter_value.0;
            +    println!("{}", counter_int_value);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/data-types.html b/v0.13.0/data-types/data-types.html new file mode 100644 index 0000000000..3360a9b291 --- /dev/null +++ b/v0.13.0/data-types/data-types.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Data Types | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Data Types

            +

            The driver maps database data types to matching Rust types +to achieve seamless sending and receiving of CQL values.

            +

            See the following chapters for examples on how to send and receive each data type.

            +

            See Query values for more information about sending values in queries.
            +See Query result for more information about reading values from queries

            +

            Database types and their Rust equivalents:

            +
              +
            • Boolean <—-> bool

            • +
            • Tinyint <—-> i8

            • +
            • Smallint <—-> i16

            • +
            • Int <—-> i32

            • +
            • BigInt <—-> i64

            • +
            • Float <—-> f32

            • +
            • Double <—-> f64

            • +
            • Ascii, Text, Varchar <—-> &str, String

            • +
            • Counter <—-> value::Counter

            • +
            • Blob <—-> Vec<u8>

            • +
            • Inet <—-> std::net::IpAddr

            • +
            • Uuid <—-> uuid::Uuid

            • +
            • Timeuuid <—-> value::CqlTimeuuid

            • +
            • Date <—-> value::CqlDate, chrono::NaiveDate, time::Date

            • +
            • Time <—-> value::CqlTime, chrono::NaiveTime, time::Time

            • +
            • Timestamp <—-> value::CqlTimestamp, chrono::DateTime<Utc>, time::OffsetDateTime

            • +
            • Duration <—-> value::CqlDuration

            • +
            • Decimal <—-> value::CqlDecimal, bigdecimal::Decimal

            • +
            • Varint <—-> value::CqlVarint, num_bigint::BigInt (v0.3 and v0.4)

            • +
            • List <—-> Vec<T>

            • +
            • Set <—-> Vec<T>

            • +
            • Map <—-> std::collections::HashMap<K, V>

            • +
            • Tuple <—-> Rust tuples

            • +
            • UDT (User defined type) <—-> Custom user structs with macros

            • +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/date.html b/v0.13.0/data-types/date.html new file mode 100644 index 0000000000..4b81c513b0 --- /dev/null +++ b/v0.13.0/data-types/date.html @@ -0,0 +1,707 @@ + + + + + + + + + + + + + Date | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Date

            +

            Depending on feature flags, three different types can be used to interact with date.

            +

            Internally date is represented as number of days since +-5877641-06-23 i.e. 2^31 days before unix epoch.

            +
            +

            CqlDate

            +

            Without any extra features enabled, only frame::value::CqlDate is available. It’s an +u32 wrapper and it matches the internal date representation.

            +

            However, for most use cases other types are more practical. See following sections for chrono and time.

            +
            use scylla::frame::value::CqlDate;
            +use scylla::IntoTypedRows;
            +
            +// 1970-01-08
            +let to_insert = CqlDate((1 << 31) + 7);
            +
            +// Insert date into the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read raw Date from the table
            +if let Some(rows) = session
            +    .query("SELECT a FROM keyspace.table", &[])
            +    .await?
            +    .rows
            +{
            +    for row in rows.into_typed::<(CqlDate,)>() {
            +        let (date_value,): (CqlDate,) = row?;
            +    }
            +}
            +
            +
            +
            +
            +

            chrono::NaiveDate

            +

            If full range is not required and chrono feature is enabled, +chrono::NaiveDate can be used. +chrono::NaiveDate supports dates from +-262145-01-01 to 262143-12-31.

            +
            use chrono::NaiveDate;
            +use scylla::IntoTypedRows;
            +
            +// 2021-03-24
            +let to_insert = NaiveDate::from_ymd_opt(2021, 3, 24).unwrap();
            +
            +// Insert date into the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read NaiveDate from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(NaiveDate,)>()?;
            +while let Some((date_value,)) = iter.next().transpose()? {
            +    println!("{:?}", date_value);
            +}
            +
            +
            +
            +
            +

            time::Date

            +

            Alternatively, time feature can be used to enable support of +time::Date. +time::Date’s value range depends on feature flags, see its +documentation to get more info.

            +
            use scylla::IntoTypedRows;
            +use time::{Date, Month};
            +
            +// 2021-03-24
            +let to_insert = Date::from_calendar_date(2021, Month::March, 24).unwrap();
            +
            +// Insert date into the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read Date from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(Date,)>()?;
            +while let Some((date_value,)) = iter.next().transpose()? {
            +    println!("{:?}", date_value);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/decimal.html b/v0.13.0/data-types/decimal.html new file mode 100644 index 0000000000..e919a18d94 --- /dev/null +++ b/v0.13.0/data-types/decimal.html @@ -0,0 +1,668 @@ + + + + + + + + + + + + + Decimal | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Decimal

            +

            Decimal is represented as value::CqlDecimal or bigdecimal::BigDecimal

            +
            +

            value::CqlDecimal

            +

            Without any feature flags, the user can interact with decimal type by making use of value::CqlDecimal which is a very simple wrapper representing the value as signed binary number in big-endian order with a 32-bit scale.

            +
            use scylla::IntoTypedRows;
            +use scylla::frame::value::CqlDecimal;
            +use std::str::FromStr;
            +
            +// Insert a decimal (123.456) into the table
            +let to_insert: CqlDecimal =
            +        CqlDecimal::from_signed_be_bytes_and_exponent(vec![0x01, 0xE2, 0x40], 3);
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a decimal from the table
            +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
            +    for row in rows.into_typed::<(CqlDecimal,)>() {
            +        let (decimal_value,): (CqlDecimal,) = row?;
            +    }
            +}
            +
            +
            +
            +
            +

            bigdecimal::BigDecimal

            +

            To make use of bigdecimal::Bigdecimal type, user should enable bigdecimal-04 crate feature.

            +
            use scylla::IntoTypedRows;
            +use bigdecimal::BigDecimal;
            +use std::str::FromStr;
            +
            +// Insert a decimal into the table
            +let to_insert: BigDecimal = BigDecimal::from_str("12345.0")?;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a decimal from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(BigDecimal,)>()?;
            +while let Some((decimal_value,)) = iter.next().transpose()? {
            +    println!("{:?}", decimal_value);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/duration.html b/v0.13.0/data-types/duration.html new file mode 100644 index 0000000000..d96434c6dd --- /dev/null +++ b/v0.13.0/data-types/duration.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + + Duration | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Duration

            +

            Duration is represented as CqlDuration\

            +
            use scylla::IntoTypedRows;
            +use scylla::frame::value::CqlDuration;
            +
            +// Insert some duration into the table
            +let to_insert: CqlDuration = CqlDuration { months: 1, days: 2, nanoseconds: 3 };
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read duration from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(CqlDuration,)>()?;
            +while let Some((duration_value,)) = iter.next().transpose()? {
            +    println!("{:?}", duration_value);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/inet.html b/v0.13.0/data-types/inet.html new file mode 100644 index 0000000000..601e23324d --- /dev/null +++ b/v0.13.0/data-types/inet.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + + Inet | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Inet

            +

            Inet is represented as std::net::IpAddr

            +
            use scylla::IntoTypedRows;
            +use std::net::{IpAddr, Ipv4Addr};
            +
            +// Insert some ip address into the table
            +let to_insert: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read inet from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(IpAddr,)>()?;
            +while let Some((inet_value,)) = iter.next().transpose()? {
            +    println!("{:?}", inet_value);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/primitive.html b/v0.13.0/data-types/primitive.html new file mode 100644 index 0000000000..7d654757b2 --- /dev/null +++ b/v0.13.0/data-types/primitive.html @@ -0,0 +1,767 @@ + + + + + + + + + + + + + Bool, Tinyint, Smallint, Int, Bigint, Float, Double | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Bool, Tinyint, Smallint, Int, Bigint, Float, Double

            +
            +

            Bool

            +

            Bool is represented as rust bool

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a bool into the table
            +let to_insert: bool = true;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a bool from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(bool,)>()?;
            +while let Some((bool_value,)) = iter.next().transpose()? {
            +    println!("{}", bool_value);
            +}
            +
            +
            +
            +
            +

            Tinyint

            +

            Tinyint is represented as rust i8

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a tinyint into the table
            +let to_insert: i8 = 123;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a tinyint from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(i8,)>()?;
            +while let Some((tinyint_value,)) = iter.next().transpose()? {
            +    println!("{:?}", tinyint_value);
            +}
            +
            +
            +
            +
            +

            Smallint

            +

            Smallint is represented as rust i16

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a smallint into the table
            +let to_insert: i16 = 12345;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a smallint from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(i16,)>()?;
            +while let Some((smallint_value,)) = iter.next().transpose()? {
            +    println!("{}", smallint_value);
            +}
            +
            +
            +
            +
            +

            Int

            +

            Int is represented as rust i32

            +
            use scylla::IntoTypedRows;
            +
            +// Insert an int into the table
            +let to_insert: i32 = 12345;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read an int from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(i32,)>()?;
            +while let Some((int_value,)) = iter.next().transpose()? {
            +    println!("{}", int_value);
            +}
            +
            +
            +
            +
            +

            Bigint

            +

            Bigint is represented as rust i64

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a bigint into the table
            +let to_insert: i64 = 12345;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a bigint from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(i64,)>()?;
            +while let Some((bigint_value,)) = iter.next().transpose()? {
            +    println!("{:?}", bigint_value);
            +}
            +
            +
            +
            +
            +

            Float

            +

            Float is represented as rust f32

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a float into the table
            +let to_insert: f32 = 123.0;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a float from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(f32,)>()?;
            +while let Some((float_value,)) = iter.next().transpose()? {
            +    println!("{:?}", float_value);
            +}
            +
            +
            +
            +
            +

            Double

            +

            Double is represented as rust f64

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a double into the table
            +let to_insert: f64 = 12345.0;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a double from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(f64,)>()?;
            +while let Some((double_value,)) = iter.next().transpose()? {
            +    println!("{:?}", double_value);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/text.html b/v0.13.0/data-types/text.html new file mode 100644 index 0000000000..d0a880793a --- /dev/null +++ b/v0.13.0/data-types/text.html @@ -0,0 +1,633 @@ + + + + + + + + + + + + + Ascii, Text, Varchar | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Ascii, Text, Varchar

            +

            Ascii, Text and Varchar are represented as &str and String

            +
            use scylla::IntoTypedRows;
            +
            +// Insert some text into the table as a &str
            +let to_insert_str: &str = "abcdef";
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_str,))
            +    .await?;
            +
            +// Insert some text into the table as a String
            +let to_insert_string: String = "abcdef".to_string();
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert_string,))
            +    .await?;
            +
            +// Read ascii/text/varchar from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(String,)>()?;
            +while let Some((text_value,)) = iter.next().transpose()? {
            +    println!("{}", text_value);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/time.html b/v0.13.0/data-types/time.html new file mode 100644 index 0000000000..0cdcc4f4d5 --- /dev/null +++ b/v0.13.0/data-types/time.html @@ -0,0 +1,705 @@ + + + + + + + + + + + + + Time | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Time

            +

            Depending on feature flags used, three different types can be used to interact with time.

            +

            Internally time is represented as number of nanoseconds since +midnight. It can’t be negative or exceed 86399999999999 (23:59:59.999999999).

            +
            +

            CqlTime

            +

            Without any extra features enabled, only frame::value::CqlTime is available. It’s an +i64 wrapper and it matches the internal time representation.

            +

            However, for most use cases other types are more practical. See following sections for chrono and time.

            +
            use scylla::frame::value::CqlTime;
            +use scylla::IntoTypedRows;
            +
            +// 64 seconds since midnight
            +let to_insert = CqlTime(64 * 1_000_000_000);
            +
            +// Insert time into the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read time from the table
            +if let Some(rows) = session
            +    .query("SELECT a FROM keyspace.table", &[])
            +    .await?
            +    .rows
            +{
            +    for row in rows.into_typed::<(CqlTime,)>() {
            +        let (time_value,): (CqlTime,) = row?;
            +    }
            +}
            +
            +
            +
            +
            +

            chrono::NaiveTime

            +

            If chrono feature is enabled, chrono::NaiveTime +can be used to interact with the database. Although chrono can represent leap seconds, they are not supported. +Attempts to convert chrono::NaiveTime with leap +second to CqlTime or write it to the database will return an error.

            +
            use chrono::NaiveTime;
            +use scylla::IntoTypedRows;
            +
            +// 01:02:03.456,789,012
            +let to_insert = NaiveTime::from_hms_nano_opt(1, 2, 3, 456_789_012);
            +
            +// Insert time into the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read time from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(NaiveTime,)>()?;
            +while let Some((time_value,)) = iter.next().transpose()? {
            +    println!("{:?}", time_value);
            +}
            +
            +
            +
            +
            +

            time::Time

            +

            If time feature is enabled, time::Time can be used to interact +with the database.

            +
            use scylla::IntoTypedRows;
            +use time::Time;
            +
            +// 01:02:03.456,789,012
            +let to_insert = Time::from_hms_nano(1, 2, 3, 456_789_012).unwrap();
            +
            +// Insert time into the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read time from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(Time,)>()?;
            +while let Some((time_value,)) = iter.next().transpose()? {
            +    println!("{:?}", time_value);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/timestamp.html b/v0.13.0/data-types/timestamp.html new file mode 100644 index 0000000000..b61b0d581c --- /dev/null +++ b/v0.13.0/data-types/timestamp.html @@ -0,0 +1,717 @@ + + + + + + + + + + + + + Timestamp | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Timestamp

            +

            Depending on feature flags, three different types can be used to interact with timestamps.

            +

            Internally timestamp is represented as +i64 describing number of milliseconds since unix epoch.

            +
            +

            CqlTimestamp

            +

            Without any extra features enabled, only frame::value::CqlTimestamp is available. It’s an +i64 wrapper and it matches the internal time representation. It’s +the only type that supports full range of values that database accepts.

            +

            However, for most use cases other types are more practical. See following sections for chrono and time.

            +
            use scylla::frame::value::CqlTimestamp;
            +use scylla::IntoTypedRows;
            +
            +// 64 seconds since unix epoch, 1970-01-01 00:01:04
            +let to_insert = CqlTimestamp(64 * 1000);
            +
            +// Write timestamp to the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read timestamp from the table
            +if let Some(rows) = session
            +    .query("SELECT a FROM keyspace.table", &[])
            +    .await?
            +    .rows
            +{
            +    for row in rows.into_typed::<(CqlTimestamp,)>() {
            +        let (timestamp_value,): (CqlTimestamp,) = row?;
            +    }
            +}
            +
            +
            +
            +
            +

            chrono::DateTime

            +

            If full value range is not required, chrono feature can be used to enable support of +chrono::DateTime. All values are expected to be converted +to UTC timezone explicitly, as timestamp doesn’t store +timezone information. Any precision finer than 1ms will be lost.

            +
            use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
            +use scylla::IntoTypedRows;
            +
            +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123
            +let to_insert = NaiveDateTime::new(
            +    NaiveDate::from_ymd_opt(1970, 1, 1).unwrap(),
            +    NaiveTime::from_hms_milli_opt(0, 1, 4, 123).unwrap(),
            +)
            +.and_utc();
            +
            +// Write timestamp to the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read timestamp from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(DateTime<Utc>,)>()?;
            +while let Some((timestamp_value,)) = iter.next().transpose()? {
            +    println!("{:?}", timestamp_value);
            +}
            +
            +
            +
            +
            +

            time::OffsetDateTime

            +

            Alternatively, time feature can be used to enable support of +time::OffsetDateTime. As +timestamp doesn’t support timezone information, time will +be corrected to UTC and timezone info will be erased on write. On read, UTC timestamp is returned. Any precision finer +than 1ms will also be lost.

            +
            use scylla::IntoTypedRows;
            +use time::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time};
            +
            +// 64.123 seconds since unix epoch, 1970-01-01 00:01:04.123
            +let to_insert = PrimitiveDateTime::new(
            +    Date::from_calendar_date(1970, Month::January, 1).unwrap(),
            +    Time::from_hms_milli(0, 1, 4, 123).unwrap(),
            +)
            +.assume_utc();
            +
            +// Write timestamp to the table
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read timestamp from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(OffsetDateTime,)>()?;
            +while let Some((timestamp_value,)) = iter.next().transpose()? {
            +    println!("{:?}", timestamp_value);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/timeuuid.html b/v0.13.0/data-types/timeuuid.html new file mode 100644 index 0000000000..3eaab02c7b --- /dev/null +++ b/v0.13.0/data-types/timeuuid.html @@ -0,0 +1,630 @@ + + + + + + + + + + + + + Timeuuid | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Timeuuid

            +

            Timeuuid is represented as value::CqlTimeuuid. +value::CqlTimeuuid is a wrapper for uuid::Uuid with custom ordering logic +which follows Scylla/Cassandra semantics.

            +
            use scylla::IntoTypedRows;
            +use scylla::frame::value::CqlTimeuuid;
            +
            +// Insert some timeuuid into the table
            +let to_insert: CqlTimeuuid = CqlTimeuuid::from_str("8e14e760-7fa8-11eb-bc66-000000000001")?;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read timeuuid from the table
            +if let Some(rows) = session.query("SELECT a FROM keyspace.table", &[]).await?.rows {
            +    for row in rows.into_typed::<(CqlTimeuuid,)>() {
            +        let (timeuuid_value,): (CqlTimeuuid,) = row?;
            +    }
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/tuple.html b/v0.13.0/data-types/tuple.html new file mode 100644 index 0000000000..0989693e3e --- /dev/null +++ b/v0.13.0/data-types/tuple.html @@ -0,0 +1,629 @@ + + + + + + + + + + + + + Tuple | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Tuple

            +

            Tuple is represented as rust tuples of max 16 elements.

            +
            use scylla::IntoTypedRows;
            +
            +// Insert a tuple of int and string into the table
            +let to_insert: (i32, String) = (1, "abc".to_string());
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a tuple of int and string from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<((i32, String),)>()?;
            +while let Some((tuple_value,)) = iter.next().transpose()? {
            +    let int_value: i32 = tuple_value.0;
            +    let string_value: String = tuple_value.1;
            +    println!("({}, {})", int_value, string_value);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/udt.html b/v0.13.0/data-types/udt.html new file mode 100644 index 0000000000..6a29e8a34e --- /dev/null +++ b/v0.13.0/data-types/udt.html @@ -0,0 +1,679 @@ + + + + + + + + + + + + + User defined types | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            User defined types

            +

            Scylla allows users to define their own data types with named fields (See the official documentation)
            +To use user defined types in the driver, you can create a corresponding struct in Rust, and use it to read and write UDT values.

            +

            For example let’s say my_type was created using this query:

            +
            CREATE TYPE ks.my_type (int_val int, text_val text)
            +
            +
            +

            To use this type in the driver, create a matching struct and derive:

            +
              +
            • SerializeCql: in order to be able to use this struct in query parameters.
              +This macro requires fields of UDT and struct to have matching names, but the order +of the fields is not required to be the same.
              +Note: you can use different name using rename attribute - see SerializeCql macro documentation.

            • +
            • FromUserType: in order to be able to use this struct in query results.
              +This macro requires fields of UDT and struct to be in the same ORDER.
              +This mismatch between SerializeCql and FromUserType requirements is a temporary situation - in the future FromUserType (or the macro that replaces it) will also require matching names.

            • +
            +
            use scylla::macros::{FromUserType, SerializeCql};
            +
            +// Define a custom struct that matches the User Defined Type created earlier.
            +// Fields must be in the same order as they are in the database and also
            +// have the same names.
            +// Wrapping a field in Option will gracefully handle null field values.
            +#[derive(Debug, FromUserType, SerializeCql)]
            +struct MyType {
            +    int_val: i32,
            +    text_val: Option<String>,
            +}
            +
            +
            +
            +

            Important
            +For deserialization, fields in the Rust struct must be defined in the same order as they are in the database. +When receiving values, the driver will (de)serialize fields one after another, without looking at field names.

            +
            +
            +

            Important
            +For serialization, by default fields in the Rust struct must be defined with the same names as they are in the database. +The driver will serialize the fields in the order defined by the UDT, matching Rust fields by name. +You can change this behaviour using macro attributes, see SerializeCql macro documentation for more information.

            +
            +

            Now it can be sent and received just like any other CQL value:

            +
            use scylla::IntoTypedRows;
            +use scylla::macros::{FromUserType, SerializeCql};
            +use scylla::cql_to_rust::FromCqlVal;
            +
            +#[derive(Debug, FromUserType, SerializeCql)]
            +struct MyType {
            +    int_val: i32,
            +    text_val: Option<String>,
            +}
            +
            +// Insert my_type into the table
            +let to_insert = MyType {
            +    int_val: 17,
            +    text_val: Some("Some string".to_string()),
            +};
            +
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read MyType from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(MyType,)>()?;
            +while let Some((my_type_value,)) = iter.next().transpose()? {
            +    println!("{:?}", my_type_value);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/uuid.html b/v0.13.0/data-types/uuid.html new file mode 100644 index 0000000000..553f63038f --- /dev/null +++ b/v0.13.0/data-types/uuid.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + + Uuid | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Uuid

            +

            Uuid is represented as uuid::Uuid.

            +
            use scylla::IntoTypedRows;
            +use uuid::Uuid;
            +
            +// Insert some uuid into the table
            +let to_insert: Uuid = Uuid::parse_str("8e14e760-7fa8-11eb-bc66-000000000001")?;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read uuid from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(Uuid,)>()?;
            +while let Some((uuid_value,)) = iter.next().transpose()? {
            +    println!("{:?}", uuid_value);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/data-types/varint.html b/v0.13.0/data-types/varint.html new file mode 100644 index 0000000000..caeb90c1d4 --- /dev/null +++ b/v0.13.0/data-types/varint.html @@ -0,0 +1,654 @@ + + + + + + + + + + + + + Varint | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Varint

            +

            Varint is represented as value::CqlVarint or num_bigint::BigInt.

            +
            +

            num_bigint::BigInt

            +

            To make use of num_bigint::BigInt type, user should enable one of the available feature flags (num-bigint-03 or num-bigint-04). They enable support for num_bigint::BigInt v0.3 and v0.4 accordingly.

            +
            +
            +

            value::CqlVarint

            +

            Without any feature flags, the user can interact with Varint type by making use of value::CqlVarint which +is a very simple wrapper representing the value as signed binary number in big-endian order.

            +
            +
            +

            Example

            +
            use scylla::IntoTypedRows;
            +use num_bigint::BigInt;
            +use std::str::FromStr;
            +
            +// Insert a varint into the table
            +let to_insert: BigInt = BigInt::from_str("12345")?;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +// Read a varint from the table
            +let result = session.query("SELECT a FROM keyspace.table", &[]).await?;
            +let mut iter = result.rows_typed::<(BigInt,)>()?;
            +while let Some((varint_value,)) = iter.next().transpose()? {
            +    println!("{:?}", varint_value);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/execution-profiles/create-and-use.html b/v0.13.0/execution-profiles/create-and-use.html new file mode 100644 index 0000000000..2766df2fee --- /dev/null +++ b/v0.13.0/execution-profiles/create-and-use.html @@ -0,0 +1,685 @@ + + + + + + + + + + + + + Creating a profile and setting it | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Creating a profile and setting it

            +
            +

            Example

            +

            To create an ExecutionProfile and attach it as default for Session:

            +
            use scylla::{Session, SessionBuilder};
            +use scylla::statement::Consistency;
            +use scylla::transport::ExecutionProfile;
            +
            +let profile = ExecutionProfile::builder()
            +    .consistency(Consistency::LocalOne)
            +    .request_timeout(None) // no request timeout
            +    .build();
            +
            +let handle = profile.into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .default_execution_profile_handle(handle)
            +    .build()
            +    .await?;
            +
            +
            +
            +
            +

            Example

            +

            To create an ExecutionProfile and attach it to a Query:

            +
            use scylla::query::Query;
            +use scylla::statement::Consistency;
            +use scylla::transport::ExecutionProfile;
            +use std::time::Duration;
            +
            +let profile = ExecutionProfile::builder()
            +    .consistency(Consistency::All)
            +    .request_timeout(Some(Duration::from_secs(30)))
            +    .build();
            +
            +let handle = profile.into_handle();
            +
            +let mut query1 = Query::from("SELECT * FROM ks.table");
            +query1.set_execution_profile_handle(Some(handle.clone()));
            +
            +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?");
            +query2.set_execution_profile_handle(Some(handle));
            +
            +
            +
            +
            +

            Example

            +

            To create an ExecutionProfile based on another profile:

            +
            use scylla::statement::Consistency;
            +use scylla::transport::ExecutionProfile;
            +use std::time::Duration;
            +
            +let base_profile = ExecutionProfile::builder()
            +    .request_timeout(Some(Duration::from_secs(30)))
            +    .build();
            +
            +let profile = base_profile.to_builder()
            +    .consistency(Consistency::All)
            +    .build();
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/execution-profiles/execution-profiles.html b/v0.13.0/execution-profiles/execution-profiles.html new file mode 100644 index 0000000000..9d80c0104e --- /dev/null +++ b/v0.13.0/execution-profiles/execution-profiles.html @@ -0,0 +1,619 @@ + + + + + + + + + + + + + Execution profiles | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Execution profiles

            +

            Execution profiles are a way to group various query execution configuration options together. Profiles can be created to represent different workloads, which can be run conveniently on a single session.

            +

            The settings that an execution profile encapsulates are as follows:

            +
              +
            • consistency

            • +
            • serial consistency

            • +
            • request timeout

            • +
            • load balancing policy

            • +
            • retry policy

            • +
            • speculative execution policy

            • +
            +

            There are two classes of objects related to execution profiles: ExecutionProfile and ExecutionProfileHandle. The former is simply an immutable set of the settings. The latter is a handle that at particular moment points to some ExecutionProfile (but during its lifetime, it can change the profile it points at). Handles are assigned to Sessions and Statements.
            +
            +At any moment, handles can be remapped to point to another ExecutionProfile. This allows convenient switching between workloads for all Sessions and/or Statements that, for instance, share common characteristics.

            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/execution-profiles/maximal-example.html b/v0.13.0/execution-profiles/maximal-example.html new file mode 100644 index 0000000000..9893c993d5 --- /dev/null +++ b/v0.13.0/execution-profiles/maximal-example.html @@ -0,0 +1,655 @@ + + + + + + + + + + + + + All options supported by a profile | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            All options supported by a profile

            +
            +

            Example

            +

            ExecutionProfile supports all the following options:

            +
            use scylla::query::Query;
            +use scylla::speculative_execution::SimpleSpeculativeExecutionPolicy;
            +use scylla::statement::{Consistency, SerialConsistency};
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::load_balancing::DefaultPolicy;
            +use scylla::transport::retry_policy::FallthroughRetryPolicy;
            +use std::{sync::Arc, time::Duration};
            +
            +let profile = ExecutionProfile::builder()
            +    .consistency(Consistency::All)
            +    .serial_consistency(Some(SerialConsistency::Serial))
            +    .request_timeout(Some(Duration::from_secs(30)))
            +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
            +    .load_balancing_policy(Arc::new(DefaultPolicy::default()))
            +    .speculative_execution_policy(
            +        Some(
            +            Arc::new(
            +                SimpleSpeculativeExecutionPolicy {
            +                    max_retry_count: 3,
            +                    retry_interval: Duration::from_millis(100),
            +                }
            +            )
            +        )
            +    )
            +    .build();
            +
            +let mut query = Query::from("SELECT * FROM ks.table");
            +query.set_execution_profile_handle(Some(profile.into_handle()));
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/execution-profiles/priority.html b/v0.13.0/execution-profiles/priority.html new file mode 100644 index 0000000000..b45375927e --- /dev/null +++ b/v0.13.0/execution-profiles/priority.html @@ -0,0 +1,667 @@ + + + + + + + + + + + + + Priorities of execution settings | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Priorities of execution settings

            +

            You always have a default execution profile set for the Session, either the default one or overridden upon Session creation. Moreover, you can set a profile for specific statements, in which case the statement’s profile has higher priority. Some options are also available for specific statements to be set directly on them, such as request timeout and consistency. In such case, the directly set options are preferred over those specified in execution profiles.

            +
            +

            Recap
            +Priorities are as follows:
            +Session’s default profile < Statement’s profile < options set directly on a Statement

            +
            +
            +

            Example

            +

            Priorities of execution profiles and directly set options:

            +
            use scylla::{Session, SessionBuilder};
            +use scylla::query::Query;
            +use scylla::statement::Consistency;
            +use scylla::transport::ExecutionProfile;
            +
            +let session_profile = ExecutionProfile::builder()
            +    .consistency(Consistency::One)
            +    .build();
            +
            +let query_profile = ExecutionProfile::builder()
            +    .consistency(Consistency::Two)
            +    .build();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .default_execution_profile_handle(session_profile.into_handle())
            +    .build()
            +    .await?;
            +
            +let mut query = Query::from("SELECT * FROM ks.table");
            +
            +// Query is not assigned any specific profile, so session's profile is applied.
            +// Therefore, the query will be executed with Consistency::One.
            +session.query(query.clone(), ()).await?;
            +
            +query.set_execution_profile_handle(Some(query_profile.into_handle()));
            +// Query's profile is applied.
            +// Therefore, the query will be executed with Consistency::Two.
            +session.query(query.clone(), ()).await?;
            +
            +query.set_consistency(Consistency::Three);
            +// An option is set directly on the query.
            +// Therefore, the query will be executed with Consistency::Three.
            +session.query(query, ()).await?;
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/execution-profiles/remap.html b/v0.13.0/execution-profiles/remap.html new file mode 100644 index 0000000000..cd930279bd --- /dev/null +++ b/v0.13.0/execution-profiles/remap.html @@ -0,0 +1,690 @@ + + + + + + + + + + + + + Remapping execution profile handles | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Remapping execution profile handles

            +

            ExecutionProfileHandles can be remapped to another ExecutionProfile, and the change affects all sessions and statements that have been assigned that handle. This enables quick workload switches.

            +

            Example mapping:

            +
              +
            • session1 -> handle1 -> profile1

            • +
            • statement1 -> handle1 -> profile1

            • +
            • statement2 -> handle2 -> profile2

            • +
            +

            We can now remap handle2 to profile1, so that the mapping for statement2 becomes as follows:

            +
              +
            • statement2 -> handle2 -> profile1

            • +
            +

            We can also change statement1’s handle to handle2, and remap handle1 to profile2, yielding:

            +
              +
            • session1 -> handle1 -> profile2

            • +
            • statement1 -> handle2 -> profile1

            • +
            • statement2 -> handle2 -> profile1

            • +
            +

            As you can see, profiles are a powerful and convenient way to define and modify your workloads.

            +
            +

            Example

            +

            Below, the remaps described above are followed in code.

            +
            use scylla::{Session, SessionBuilder};
            +use scylla::query::Query;
            +use scylla::statement::Consistency;
            +use scylla::transport::ExecutionProfile;
            +
            +let profile1 = ExecutionProfile::builder()
            +    .consistency(Consistency::One)
            +    .build();
            +
            +let profile2 = ExecutionProfile::builder()
            +    .consistency(Consistency::Two)
            +    .build();
            +
            +let mut handle1 = profile1.clone().into_handle();
            +let mut handle2 = profile2.clone().into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .default_execution_profile_handle(handle1.clone())
            +    .build()
            +    .await?;
            +
            +let mut query1 = Query::from("SELECT * FROM ks.table");
            +let mut query2 = Query::from("SELECT pk FROM ks.table WHERE pk = ?");
            +
            +query1.set_execution_profile_handle(Some(handle1.clone()));
            +query2.set_execution_profile_handle(Some(handle2.clone()));
            +
            +// session1 -> handle1 -> profile1
            +// query1 -> handle1 -> profile1
            +// query2 -> handle2 -> profile2
            +
            +// We can now remap handle2 to profile1:
            +handle2.map_to_another_profile(profile1);
            +// ...so that the mapping for query2 becomes as follows:
            +// query2 -> handle2 -> profile1
            +
            +// We can also change query1's handle to handle2:
            +query1.set_execution_profile_handle(Some(handle2.clone()));
            +// ...and remap handle1 to profile2:
            +handle1.map_to_another_profile(profile2);
            +// ...yielding:
            +// session1 -> handle1 -> profile2
            +// query1 -> handle2 -> profile1
            +// query2 -> handle2 -> profile1
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/genindex.html b/v0.13.0/genindex.html new file mode 100644 index 0000000000..2eaf296be8 --- /dev/null +++ b/v0.13.0/genindex.html @@ -0,0 +1,585 @@ + + + + + + + + + + + + + Index | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + + + +
            + + + + + +
            + + +
            + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/index.html b/v0.13.0/index.html new file mode 100644 index 0000000000..59984cf608 --- /dev/null +++ b/v0.13.0/index.html @@ -0,0 +1,636 @@ + + + + + + + + + + + + + Scylla Rust Driver | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Scylla Rust Driver

            +

            This book contains documentation for scylla-rust-driver - a driver +for the Scylla database written in Rust. +Although optimized for Scylla, the driver is also compatible with Apache Cassandra®.

            +
            +

            Other documentation

            + +
            +
            +

            Contents

            + +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/load-balancing/default-policy.html b/v0.13.0/load-balancing/default-policy.html new file mode 100644 index 0000000000..b759b74e33 --- /dev/null +++ b/v0.13.0/load-balancing/default-policy.html @@ -0,0 +1,792 @@ + + + + + + + + + + + + + DefaultPolicy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            DefaultPolicy

            +

            DefaultPolicy is the default load balancing policy in Scylla Rust Driver. It +can be configured to be datacenter-aware and token-aware. Datacenter failover +for queries with non-local consistency mode is also supported.

            +
            +

            Creating a DefaultPolicy

            +

            DefaultPolicy can be created only using DefaultPolicyBuilder. The +builder() method of DefaultPolicy returns a new instance of +DefaultPolicyBuilder with the following default values:

            +
              +
            • preferences: no particular datacenter/rack preference

            • +
            • is_token_aware: true

            • +
            • permit_dc_failover: false

            • +
            • latency_awareness: None

            • +
            +

            You can use the builder methods to configure the desired settings and create a +DefaultPolicy instance:

            +
            use scylla::load_balancing::DefaultPolicy;
            +
            +let default_policy = DefaultPolicy::builder()
            +        .prefer_datacenter_and_rack("dc1".to_string(), "rack1".to_string())
            +        .token_aware(true)
            +        .permit_dc_failover(true)
            +        .build();
            +
            +
            +
            +

            Semantics of DefaultPolicy

            +
            +

            Preferences

            +

            The preferences field in DefaultPolicy allows the load balancing +policy to prioritize nodes based on their location. It has three modes:

            +
              +
            • no preference

            • +
            • preferred datacenter

            • +
            • preferred datacenter and rack

            • +
            +

            When a datacenter "my_dc" is preferred, the policy will treat nodes in "my_dc" +as “local” nodes, and nodes in other datacenters as “remote” nodes. This affects +the order in which nodes are returned by the policy when selecting nodes for +read or write operations. If no datacenter is preferred, the policy will treat +all nodes as local nodes.

            +

            preferences allow the load balancing policy to prioritize nodes based on their +availability zones (racks) in the preferred datacenter, too. When a datacenter +and a rack are preferred, the policy will first return replicas in the local rack +in the preferred datacenter, and then the other replicas in the datacenter +(followed by remote replicas). After replicas, the other node will be ordered +similarly, too (local rack nodes, local datacenter nodes, remote nodes).

            +

            When datacenter failover is disabled (permit_dc_failover is set to +false), the default policy will only include local nodes in load balancing +plans. Remote nodes will be excluded, even if they are alive and available to +serve requests.

            +
            +
            +

            Datacenter Failover

            +

            In the event of a datacenter outage or network failure, the nodes in that +datacenter may become unavailable, and clients may no longer be able to access +the data stored on those nodes. To address this, the DefaultPolicy supports +datacenter failover, which allows to route requests to nodes in other datacenters +if the local nodes are unavailable.

            +

            Datacenter failover can be enabled in DefaultPolicy by permit_dc_failover +setting in the builder. When this flag is set, the policy will prefer to return +alive remote replicas if datacenter failover is permitted and possible due to +consistency constraints.

            +
            +
            +

            Token awareness

            +

            Token awareness refers to a mechanism by which the driver is aware of the token +range assigned to each node in the cluster. Tokens are assigned to nodes to +partition the data and distribute it across the cluster.

            +

            When a user wants to read or write data, the driver can use token awareness to +route the request to the correct node based on the token range of the data +being accessed. This can help to minimize network traffic and improve +performance by ensuring that the data is accessed locally as much as possible.

            +

            In the case of DefaultPolicy, token awareness is enabled by default, meaning +that the policy will prefer to return alive local replicas if the token is +available. This means that if the client is requesting data that falls within +the token range of a particular node, the policy will try to route the request +to that node first, assuming it is alive and responsive.

            +

            Token awareness can significantly improve the performance and scalability of +applications built on Scylla. By using token awareness, users can ensure that +data is accessed locally as much as possible, reducing network overhead and +improving throughput.

            +

            Please note that for token awareness to be applied, a statement must be +prepared before being executed.

            +
            +
            +
            +

            Latency awareness

            +

            Latency awareness is a mechanism that penalises nodes whose measured recent +average latency classifies it as falling behind the others.

            +

            Every update_rate the global minimum average latency is computed, +and all nodes whose average latency is worse than exclusion_threshold +times the global minimum average latency become penalised for +retry_period. Penalisation involves putting those nodes at the very end +of the query plan. As it is often not truly beneficial to prefer +faster non-replica than replicas lagging behind the non-replicas, +this mechanism may as well worsen latencies and/or throughput.

            +
            +

            Warning

            +

            Using latency awareness is NOT recommended, unless prior +benchmarks prove its beneficial impact on the specific workload’s +performance. Use with caution.

            +
            +
            +
            +

            Creating a latency aware DefaultPolicy

            +
            use scylla::load_balancing::{
            +    LatencyAwarenessBuilder, DefaultPolicy
            +};
            +use std::time::Duration;
            +
            +let latency_awareness_builder = LatencyAwarenessBuilder::new()
            +    .exclusion_threshold(3.)
            +    .update_rate(Duration::from_secs(3))
            +    .retry_period(Duration::from_secs(30))
            +    .minimum_measurements(200);
            +
            +let policy = DefaultPolicy::builder()
            +        // Here further customisation is, of course, possible.
            +        // e.g.: .prefer_datacenter(...)
            +        .latency_awareness(latency_awareness_builder)
            +        .build();
            +
            +
            +
            use scylla::load_balancing::DefaultPolicy;
            +
            +let default_policy = DefaultPolicy::builder()
            +        .prefer_datacenter("dc1".to_string())
            +        .token_aware(true)
            +        .permit_dc_failover(true)
            +        .build();
            +
            +
            +
            +
            +

            Node order in produced plans

            +

            The DefaultPolicy prefers to return nodes in the following order:

            +
              +
            1. Alive local replicas (if token is available & token awareness is enabled)

            2. +
            3. Alive remote replicas (if datacenter failover is permitted & possible due to consistency constraints)

            4. +
            5. Alive local nodes

            6. +
            7. Alive remote nodes (if datacenter failover is permitted & possible due to consistency constraints)

            8. +
            9. Enabled down nodes +And only if latency awareness is enabled:

            10. +
            11. Penalised: alive local replicas, alive remote replicas, … (in order as above).

            12. +
            +

            If no preferred datacenter is specified, all nodes are treated as local ones.

            +

            Replicas in the same priority groups are shuffled[1]. Non-replicas are randomly +rotated (similarly to a round robin with a random index).

            +
            + +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/load-balancing/load-balancing.html b/v0.13.0/load-balancing/load-balancing.html new file mode 100644 index 0000000000..8085a47b2f --- /dev/null +++ b/v0.13.0/load-balancing/load-balancing.html @@ -0,0 +1,726 @@ + + + + + + + + + + + + + Load balancing | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Load balancing

            +
            +

            Introduction

            +

            The driver uses a load balancing policy to determine which node(s) and shard(s) +to contact when executing a query. Load balancing policies implement the +LoadBalancingPolicy trait, which contains methods to generate a load +balancing plan based on the query information and the state of the cluster.

            +

            Load balancing policies do not influence to which nodes connections are +being opened. For a node connection blacklist configuration refer to +scylla::transport::host_filter::HostFilter, which can be set session-wide +using SessionBuilder::host_filter method.

            +

            In this chapter, “target” will refer to a pair <node, optional shard>.

            +
            +
            +

            Plan

            +

            When a query is prepared to be sent to the database, the load balancing policy +constructs a load balancing plan. This plan is essentially a list of targets to +which the driver will try to send the query. The first elements of the plan are +the targets which are the best to contact (e.g. they might be replicas for the +requested data or have the best latency).

            +
            +
            +

            Policy

            +

            The Scylla/Cassandra driver provides a default load balancing policy (see +Default Policy for details), but you can +also implement your own custom policies that better suit your specific use +case. To use a custom policy, you simply need to implement the +LoadBalancingPolicy trait and pass an instance of your custom policy to the +used execution profile.

            +

            Our recommendation is to use Default Policy with token- +awareness enabled and latency-awareness disabled.

            +
            +
            +

            Configuration

            +

            Load balancing policies can be configured via execution profiles. In the code +sample provided, a new execution profile is created using +ExecutionProfile::builder(), and the load balancing policy is set to the +DefaultPolicy using .load_balancing_policy(policy).

            +

            The newly created execution profile is then converted to a handle using +.into_handle(), and passed as the default execution profile to the +SessionBuilder using .default_execution_profile_handle(handle).

            +
            use scylla::SessionBuilder;
            +use scylla::load_balancing::DefaultPolicy;
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::session::Session;
            +use std::sync::Arc;
            +
            +let policy = Arc::new(DefaultPolicy::default());
            +
            +let profile = ExecutionProfile::builder()
            +    .load_balancing_policy(policy)
            +    .build();
            +let handle = profile.into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node(&uri)
            +    .default_execution_profile_handle(handle)
            +    .build()
            +    .await?;
            +
            +
            +

            In addition to being able to configure load balancing policies through +execution profiles at the session level, the driver also allow for setting +execution profile handles on a per-query basis. This means that for each query, +a specific execution profile can be selected with a customized load balancing +settings.

            +
            +
            +

            LoadBalancingPolicy trait

            +
            +

            pick and fallback:

            +

            Most queries are sent successfully on the first try. In such cases, only the +first element of the load balancing plan is needed, so it’s usually unnecessary +to compute entire load balancing plan. To optimize this common case, the +LoadBalancingPolicy trait provides two methods: pick and fallback.

            +

            pick returns the first target to contact for a given query, which is usually +the best based on a particular load balancing policy.

            +

            fallback, returns an iterator that provides the rest of the targets in the +load balancing plan. fallback is called when using the initial picked +target fails (or when executing speculatively) or when pick returned None.

            +

            It’s possible for the fallback method to include the same target that was +returned by the pick method. In such cases, the query execution layer filters +out the picked target from the iterator returned by fallback.

            +
            +
            +

            on_query_success and on_query_failure:

            +

            The on_query_success and on_query_failure methods are useful for load +balancing policies because they provide feedback on the performance and health +of the nodes in the cluster.

            +

            When a query is successfully executed, the on_query_success method is called +and can be used by the load balancing policy to update its internal state. For +example, a policy might use the latency of the successful query to update its +latency statistics for each node in the cluster. This information can be used +to make decisions about which nodes to contact in the future.

            +

            On the other hand, when a query fails to execute, the on_query_failure method +is called and provides information about the failure. The error message +returned by Cassandra can help determine the cause of the failure, such as a +node being down or overloaded. The load balancing policy can use this +information to update its internal state and avoid contacting the same node +again until it’s recovered.

            +
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/logging/logging.html b/v0.13.0/logging/logging.html new file mode 100644 index 0000000000..4ac54a3640 --- /dev/null +++ b/v0.13.0/logging/logging.html @@ -0,0 +1,641 @@ + + + + + + + + + + + + + Logging | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Logging

            +

            The driver uses the tracing crate for all logs.
            +To view the logs you have to create a tracing subscriber to which all logs will be written.

            +

            To just print the logs you can use the default subscriber:

            +
            use tracing::info;
            +
            +#[tokio::main]
            +async fn main() -> Result<(), Box<dyn Error>> {
            +    // Install global collector configured based on RUST_LOG env var
            +    // This collector will receive logs from the driver
            +    tracing_subscriber::fmt::init();
            +
            +    let uri = std::env::var("SCYLLA_URI")
            +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
            +
            +    info!("Connecting to {}", uri);
            +
            +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
            +    session
            +        .query(
            +            "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \
            +            {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}",
            +            &[],
            +        )
            +        .await?;
            +
            +    // This query should generate a warning message
            +    session.query("USE ks", &[]).await?;
            +
            +    Ok(())
            +}
            +
            +
            +

            To start this example execute:

            +
            RUST_LOG=info cargo run
            +
            +
            +

            The full example is available in the examples folder

            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/metrics/metrics.html b/v0.13.0/metrics/metrics.html new file mode 100644 index 0000000000..ccca65190b --- /dev/null +++ b/v0.13.0/metrics/metrics.html @@ -0,0 +1,645 @@ + + + + + + + + + + + + + Driver metrics | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Driver metrics

            +

            During operation the driver collects various metrics.

            +

            They can be accessed at any moment using Session::get_metrics()

            +
            +

            Collected metrics:

            +
              +
            • Query latencies

            • +
            • Total number of nonpaged queries

            • +
            • Number of errors during nonpaged queries

            • +
            • Total number of paged queries

            • +
            • Number of errors during paged queries

            • +
            • Number of retries

            • +
            +
            +
            +

            Example

            +
            let metrics = session.get_metrics();
            +
            +println!("Queries requested: {}", metrics.get_queries_num());
            +println!("Iter queries requested: {}", metrics.get_queries_iter_num());
            +println!("Errors occurred: {}", metrics.get_errors_num());
            +println!("Iter errors occurred: {}", metrics.get_errors_iter_num());
            +println!("Average latency: {}", metrics.get_latency_avg_ms().unwrap());
            +println!(
            +    "99.9 latency percentile: {}",
            +    metrics.get_latency_percentile_ms(99.9).unwrap()
            +);
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/migration-guides/0.11-serialization.html b/v0.13.0/migration-guides/0.11-serialization.html new file mode 100644 index 0000000000..da93b9e3db --- /dev/null +++ b/v0.13.0/migration-guides/0.11-serialization.html @@ -0,0 +1,723 @@ + + + + + + + + + + + + + Adjusting code to changes in serialization API introduced in 0.11 | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Adjusting code to changes in serialization API introduced in 0.11

            +
            +

            Background

            +

            When executing a statement through the CQL protocol, values for the bind markers are sent in a serialized, untyped form. In order to implement a safer and more robust interface, drivers can use the information returned after preparing a statement to check the type of data provided by the user against the actual types of the bind markers.

            +

            Before 0.11, the driver couldn’t do this kind of type checking. For example, in the case of non-batch queries, the only information about the user data it has is that it implements ValueList - defined as follows:

            +
            pub trait ValueList {
            +    fn serialized(&self) -> SerializedResult<'_>;
            +    fn write_to_request(&self, buf: &mut impl BufMut) -> Result<(), SerializeValuesError>;
            +}
            +
            +
            +

            The driver would naively serialize the data and hope that the user took care to send correct types of values. Failing to do so would, in the best case, fail on the DB-side validation; in the worst case, the data in its raw form may be reinterpreted as another type in an unintended manner.

            +

            Another problem is that the information from the prepared statement response is required to robustly serialize user defined types, as UDTs require their fields to be serialized in the same order as they are defined in the database schema. The IntoUserType macro which implements Rust struct -> UDT serialization just expects that the order of the Rust struct fields matches the schema, but ensuring this can be very cumbersome for the users.

            +

            In version 0.11, a new set of traits is introduced and the old ones are deprecated. The new traits receive more information during serialization such as names of the column/bind markers and their types, which allows to fix the issues mentioned in the previous section.

            +
            +
            +

            Old vs. new

            +

            Both the old and the new APIs are based on three core traits:

            +
              +
            • Value - called SerializeCql in the new API. A type that can serialize itself to a single CQL value. For example, i32 serializes itself into a representation that is compatible with the CQL int type.

            • +
            • ValueList - called SerializeRow in the new API. A type that can serialize itself as a list of values for a CQL statement. For example, a (i32, &str) produces a list of two values which can be used in a query with two bind markers, e.g. SELECT * FROM table WHERE pk = ? AND ck = ?. Optionally, values in the produced list may be associated with names which is useful when using it with a query with named bind markers, e.g. SELECT * FROM table WHERE pk = :pk AND ck = :ck.

            • +
            • LegacyBatchValues, previously named BatchValues - in new API replaced with new trait called (again) BatchValues. Represents a source of data for a batch request. It is essentially equivalent to a list of ValueList, one for each statement in the batch. For example, ((1, 2), (3, 4, 5)) can be used for a batch with two statements, the first one having two bind markers and the second one having three.

            • +
            +

            All methods which take one of the old traits were changed to take the new trait - notably, this includes Session::query, (Caching)Session::execute, (Caching)Session::batch.

            +

            The driver comes a set of impls of those traits which allow to represent any CQL type (for example, see Data Types page for a list of for which Value and SerializeCql is implemented). If the driver implements an old trait for some type, then it also provides implements the new trait for the same type.

            +
            +
            +

            Migration scenarios

            +
            +

            Different default behavior in SerializeRow/SerializeCql macros

            +

            By default, the SerializeRow and SerializeCql will match the fields in the Rust struct by name to bind marker names (in case of SerializeRow) or UDT field names (in case of SerializeCql). This is different from the old ValueList and IntoUserType macros which did not look at the field names at all and would expect the user to order the fields correctly. While the new behavior is much more ergonomic, you might have reasons not to use it.

            +
            +

            NOTE: The deserialization macro counterparts FromRow and FromUserType have the same limitation as the old serialization macros - they require struct fields to be properly ordered. While a similar rework is planned for the deserialization traits in a future release, for the time being it might not be worth keeping the column names in sync with the database.

            +
            +

            In order to bring the old behavior to the new macros (the only difference being type checking which cannot be disabled right now) you can configure it using attributes, as shown in the snippet below:

            +
            use scylla::SerializeCql;
            +
            +// The exact same attributes apply to the `SerializeRow` macro and their
            +// effect is completely analogous.
            +#[derive(SerializeCql)]
            +#[scylla(flavor = "enforce_order", skip_name_checks)]
            +struct Person {
            +    name: String,
            +    surname: String,
            +    age: i16,
            +}
            +
            +
            +

            Refer to the API reference page for the SerializeRow and SerializeCql macros in the scylla crate to learn more about the supported attributes and their meaning.

            +
            +
            +

            Preparing is mandatory with a non-empty list of values

            +
            +

            NOTE: The considerations in this section only concerns users of the Session API, CachingSession is not affected as it already does preparation before execute and caches the result.

            +
            +

            As explained in the Background section, the driver uses data returned from the database after preparing a statement in order to implement type checking. As the new API makes type checking mandatory, the driver must prepare the statement so that the data for the bind markers can be type checked. It is done in case of the existing methods which used to send unprepared statements: Session::query and Session::batch.

            +
            +

            NOTE: The driver will skip preparation if it detects that the list of values for the statement is empty, as there is nothing to be type checked.

            +
            +

            If you send simple statements along with non-empty lists of values, the slowdown will be as follows:

            +
              +
            • For Session::query, the driver will prepare the statement before sending it, incurring an additional round-trip.

            • +
            • For Session::batch, the driver will send a prepare request for each unique unprepared statement with a non-empty list of values. This is done serially!

            • +
            +

            In both cases, if the additional roundtrips are unacceptable, you should prepare the statements beforehand and reuse them - which aligns with our general recommendation against use of simple statements in performance sensitive scenarios.

            +
            +
            +

            Migrating from old to new traits gradually

            +

            In some cases, migration will be as easy as changing occurrences of IntoUserType to SerializeCql and ValueList to SerializeRow and adding some atributes for procedural macros. However, if you have a large enough codebase or some custom, complicated implementations of the old traits then you might not want to migrate everything at once. To support gradual migration, the old traits were not removed but rather deprecated, and we introduced some additional utilities.

            +
            +

            Converting an object implementing an old trait to a new trait

            +

            We provide a number of newtype wrappers:

            +
              +
            • ValueAdapter - implements SerializeCql if the type wrapped over implements Value,

            • +
            • ValueListAdapter - implements SerializeRow if the type wrapped over implements ValueList,

            • +
            • LegacyBatchValuesAdapter - implements BatchValues if the type wrapped over implements LegacyBatchValues.

            • +
            +

            Note that these wrappers are not zero cost and incur some overhead: in case of ValueAdapter and ValueListAdapter, the data is first written into a newly allocated buffer and then rewritten to the final buffer. In case of LegacyBatchValuesAdapter there shouldn’t be any additional allocations unless the implementation has an efficient, non-default Self::LegacyBatchValuesIterator::write_next_to_request implementation (which is not the case for the built-in impls).

            +

            Naturally, the implementations provided by the wrappers are not type safe as they directly use methods from the old traits.

            +

            Conversion in the other direction is not possible.

            +
            +
            +

            Custom implementations of old traits

            +

            It is possible to directly generate an impl of SerializeRow and SerializeCql on a type which implements, respectively, ValueList or Value, without using the wrappers from the previous section. The following macros are provided:

            +
              +
            • impl_serialize_cql_via_value - implements SerializeCql if the type wrapped over implements Value,

            • +
            • impl_serialize_row_via_value_list - implements SerializeRow if the type wrapped over implements ValueList,

            • +
            +

            The implementations are practically as those generated by the wrappers described in the previous section.

            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/migration-guides/migration-guides.html b/v0.13.0/migration-guides/migration-guides.html new file mode 100644 index 0000000000..5016549ca2 --- /dev/null +++ b/v0.13.0/migration-guides/migration-guides.html @@ -0,0 +1,609 @@ + + + + + + + + + + + + + Migration guides | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Migration guides

            + +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/objects.inv b/v0.13.0/objects.inv new file mode 100644 index 0000000000..5d605ef479 Binary files /dev/null and b/v0.13.0/objects.inv differ diff --git a/v0.13.0/queries/batch.html b/v0.13.0/queries/batch.html new file mode 100644 index 0000000000..4215f12f83 --- /dev/null +++ b/v0.13.0/queries/batch.html @@ -0,0 +1,746 @@ + + + + + + + + + + + + + Batch statement | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Batch statement

            +

            A batch statement allows to execute many data-modifying statements at once.
            +These statements can be simple or prepared.
            +Only INSERT, UPDATE and DELETE statements are allowed.

            +
            use scylla::batch::Batch;
            +use scylla::query::Query;
            +use scylla::prepared_statement::PreparedStatement;
            +
            +// Create a batch statement
            +let mut batch: Batch = Default::default();
            +
            +// Add a simple statement to the batch using its text
            +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(1, 2)");
            +
            +// Add a simple statement created manually to the batch
            +let simple: Query = Query::new("INSERT INTO ks.tab (a, b) VALUES(3, 4)");
            +batch.append_statement(simple);
            +
            +// Add a prepared statement to the batch
            +let prepared: PreparedStatement = session
            +    .prepare("INSERT INTO ks.tab (a, b) VALUES(?, 6)")
            +    .await?;
            +batch.append_statement(prepared);
            +
            +// Specify bound values to use with each statement
            +let batch_values = ((),
            +                    (),
            +                    (5_i32,));
            +
            +// Run the batch
            +session.batch(&batch, batch_values).await?;
            +
            +
            +
            +

            Warning
            +Using simple statements with bind markers in batches is strongly discouraged. +For each simple statement with a non-empty list of values in the batch, +the driver will send a prepare request, and it will be done sequentially. +Results of preparation are not cached between Session::batch calls. +Consider preparing the statements before putting them into the batch.

            +
            +
            +

            Preparing a batch

            +

            Instead of preparing each statement individually, it’s possible to prepare a whole batch at once:

            +
            use scylla::batch::Batch;
            +
            +// Create a batch statement with unprepared statements
            +let mut batch: Batch = Default::default();
            +batch.append_statement("INSERT INTO ks.simple_unprepared1 VALUES(?, ?)");
            +batch.append_statement("INSERT INTO ks.simple_unprepared2 VALUES(?, ?)");
            +
            +// Prepare all statements in the batch at once
            +let prepared_batch: Batch = session.prepare_batch(&batch).await?;
            +
            +// Specify bound values to use with each statement
            +let batch_values = ((1_i32, 2_i32),
            +                    (3_i32, 4_i32));
            +
            +// Run the prepared batch
            +session.batch(&prepared_batch, batch_values).await?;
            +
            +
            +
            +
            +

            Batch options

            +

            You can set various options by operating on the Batch object.
            +For example to change consistency:

            +
            use scylla::batch::Batch;
            +use scylla::statement::Consistency;
            +
            +// Create a batch
            +let mut batch: Batch = Default::default();
            +batch.append_statement("INSERT INTO ks.tab(a) VALUES(16)");
            +
            +// Set batch consistency to One
            +batch.set_consistency(Consistency::One);
            +
            +// Run the batch
            +session.batch(&batch, ((), )).await?;
            +
            +
            +

            See Batch API documentation +for more options

            +
            +
            +

            Batch values

            +

            Batch takes a tuple of values specified just like in simple or prepared queries.

            +

            Length of batch values must be equal to the number of statements in a batch.
            +Each statement must have its values specified, even if they are empty.

            +

            Values passed to Session::batch must implement the trait BatchValues.
            +By default this includes tuples () and slices &[] of tuples and slices which implement ValueList.

            +

            Example:

            +
            use scylla::batch::Batch;
            +
            +let mut batch: Batch = Default::default();
            +
            +// A statement with two bound values
            +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(?, ?)");
            +
            +// A statement with one bound value
            +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(3, ?)");
            +
            +// A statement with no bound values
            +batch.append_statement("INSERT INTO ks.tab(a, b) VALUES(5, 6)");
            +
            +// Batch values is a tuple of 3 tuples containing values for each statement
            +let batch_values = ((1_i32, 2_i32), // Tuple with two values for the first statement
            +                    (4_i32,),       // Tuple with one value for the second statement
            +                    ());            // Empty tuple/unit for the third statement
            +
            +// Run the batch
            +// Note that the driver will prepare the first two statements, due to them
            +// not being prepared and having a non-empty list of values.
            +session.batch(&batch, batch_values).await?;
            +
            +
            +

            For more information about sending values in a statement see Query values

            +
            +
            +

            Performance

            +

            Batch statements do not use token/shard aware load balancing, batches are sent to a random node.

            +

            Use prepared queries for best performance

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/lwt.html b/v0.13.0/queries/lwt.html new file mode 100644 index 0000000000..f66105ab5f --- /dev/null +++ b/v0.13.0/queries/lwt.html @@ -0,0 +1,642 @@ + + + + + + + + + + + + + Lightweight transaction (LWT) query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Lightweight transaction (LWT) query

            +

            A lightweight transaction query can be expressed just like any other query, via Session, with the notable difference of having an additional consistency level parameter - the serial_consistency_level.

            +
            +

            Format of the query

            +

            A lightweight transaction query is not a separate type - it can be expressed just like any other queries: via SimpleQuery, PreparedStatement, batches, and so on. The difference lays in the query string itself - when it contains a condition (e.g. IF NOT EXISTS), it becomes a lightweight transaction. It’s important to remember that CQL specification requires a separate, additional consistency level to be defined for LWT queries - serial_consistency_level. The serial consistency level can only be set to two values: SerialConsistency::Serial or SerialConsistency::LocalSerial. The “local” variant makes the transaction consistent only within the same datacenter. For convenience, Scylla Rust Driver sets the default consistency level to LocalSerial, as it’s more commonly used. For cross-datacenter consistency, please remember to always override the default with SerialConsistency::Serial.

            +
            use scylla::query::Query;
            +use scylla::statement::{Consistency, SerialConsistency};
            +
            +// Create a Query manually to change the Consistency to ONE
            +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?) IF NOT EXISTS".to_string());
            +my_query.set_consistency(Consistency::One);
            +// Use cross-datacenter serial consistency
            +my_query.set_serial_consistency(Some(SerialConsistency::Serial));
            +
            +// Insert a value into the table
            +let to_insert: i32 = 12345;
            +session.query(my_query, (to_insert,)).await?;
            +
            +
            +

            The rest of the API remains identical for LWT and non-LWT queries.

            +

            See Query API documentation for more options

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/paged.html b/v0.13.0/queries/paged.html new file mode 100644 index 0000000000..2831d74e79 --- /dev/null +++ b/v0.13.0/queries/paged.html @@ -0,0 +1,740 @@ + + + + + + + + + + + + + Paged query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Paged query

            +

            Sometimes query results might not fit in a single page. Paged queries +allow to receive the whole result page by page.

            +

            Session::query_iter and Session::execute_iter take a simple query or a prepared query +and return an async iterator over result Rows.

            +
            +

            Warning
            +In case of unprepared variant (Session::query_iter) if the values are not empty +driver will first fully prepare a query (which means issuing additional request to each +node in a cluster). This will have a performance penalty - how big it is depends on +the size of your cluster (more nodes - more requests) and the size of returned +result (more returned pages - more amortized penalty). In any case, it is preferable to +use Session::execute_iter.

            +
            +
            +

            Examples

            +

            Use query_iter to perform a simple query with paging:

            +
            use scylla::IntoTypedRows;
            +use futures::stream::StreamExt;
            +
            +let mut rows_stream = session
            +    .query_iter("SELECT a, b FROM ks.t", &[])
            +    .await?
            +    .into_typed::<(i32, i32)>();
            +
            +while let Some(next_row_res) = rows_stream.next().await {
            +    let (a, b): (i32, i32) = next_row_res?;
            +    println!("a, b: {}, {}", a, b);
            +}
            +
            +
            +

            Use execute_iter to perform a prepared query with paging:

            +
            use scylla::IntoTypedRows;
            +use scylla::prepared_statement::PreparedStatement;
            +use futures::stream::StreamExt;
            +
            +let prepared: PreparedStatement = session
            +    .prepare("SELECT a, b FROM ks.t")
            +    .await?;
            +
            +let mut rows_stream = session
            +    .execute_iter(prepared, &[])
            +    .await?
            +    .into_typed::<(i32, i32)>();
            +
            +while let Some(next_row_res) = rows_stream.next().await {
            +    let (a, b): (i32, i32) = next_row_res?;
            +    println!("a, b: {}, {}", a, b);
            +}
            +
            +
            +

            Query values can be passed to query_iter and execute_iter just like in a simple query

            +
            +
            +

            Configuring page size

            +

            It’s possible to configure the size of a single page.

            +

            On a Query:

            +
            use scylla::query::Query;
            +
            +let mut query: Query = Query::new("SELECT a, b FROM ks.t");
            +query.set_page_size(16);
            +
            +let _ = session.query_iter(query, &[]).await?; // ...
            +
            +
            +

            On a PreparedStatement:

            +
            use scylla::prepared_statement::PreparedStatement;
            +
            +let mut prepared: PreparedStatement = session
            +    .prepare("SELECT a, b FROM ks.t")
            +    .await?;
            +
            +prepared.set_page_size(16);
            +
            +let _ = session.execute_iter(prepared, &[]).await?; // ...
            +
            +
            +
            +
            +

            Passing the paging state manually

            +

            It’s possible to fetch a single page from the table, extract the paging state +from the result and manually pass it to the next query. That way, the next +query will start fetching the results from where the previous one left off.

            +

            On a Query:

            +
            use scylla::query::Query;
            +
            +let paged_query = Query::new("SELECT a, b, c FROM ks.t").with_page_size(6);
            +let res1 = session.query(paged_query.clone(), &[]).await?;
            +let res2 = session
            +    .query_paged(paged_query.clone(), &[], res1.paging_state)
            +    .await?;
            +
            +
            +
            +

            Warning
            +If the values are not empty, driver first needs to send a PREPARE request +in order to fetch information required to serialize values. This will affect +performance because 2 round trips will be required instead of 1.

            +
            +

            On a PreparedStatement:

            +
            use scylla::query::Query;
            +
            +let paged_prepared = session
            +    .prepare(Query::new("SELECT a, b, c FROM ks.t").with_page_size(7))
            +    .await?;
            +let res1 = session.execute(&paged_prepared, &[]).await?;
            +let res2 = session
            +    .execute_paged(&paged_prepared, &[], res1.paging_state)
            +    .await?;
            +
            +
            +
            +
            +

            Performance

            +

            Performance is the same as in non-paged variants.
            +For the best performance use prepared queries.

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/prepared.html b/v0.13.0/queries/prepared.html new file mode 100644 index 0000000000..7240fe41a2 --- /dev/null +++ b/v0.13.0/queries/prepared.html @@ -0,0 +1,728 @@ + + + + + + + + + + + + + Prepared query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Prepared query

            +

            Prepared queries provide much better performance than simple queries, +but they need to be prepared before use.

            +
            use scylla::prepared_statement::PreparedStatement;
            +
            +// Prepare the query for later execution
            +let prepared: PreparedStatement = session
            +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
            +    .await?;
            +
            +// Run the prepared query with some values, just like a simple query
            +let to_insert: i32 = 12345;
            +session.execute(&prepared, (to_insert,)).await?;
            +
            +
            +
            +

            Warning
            +For token/shard aware load balancing to work properly, all partition key values +must be sent as bound values (see performance section)

            +
            +
            +

            Warning
            +Don’t use execute to receive large amounts of data.
            +By default the query is unpaged and might cause heavy load on the cluster. +In such cases set a page size and use a paged query instead.

            +

            When page size is set, execute will return only the first page of results.

            +
            +
            +

            Session::prepare

            +

            Session::prepare takes query text and prepares the query on all nodes and shards. +If at least one succeeds returns success.

            +
            +
            +

            Session::execute

            +

            Session::execute takes a prepared query and bound values and runs the query. +Passing values and the result is the same as in simple query.

            +
            +
            +

            Query options

            +

            To specify custom options, set them on the PreparedStatement before execution. +For example to change the consistency:

            +
            use scylla::prepared_statement::PreparedStatement;
            +use scylla::statement::Consistency;
            +
            +// Prepare the query for later execution
            +let mut prepared: PreparedStatement = session
            +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
            +    .await?;
            +
            +// Set prepared query consistency to One
            +// This is the consistency with which this query will be executed
            +prepared.set_consistency(Consistency::One);
            +
            +// Run the prepared query with some values, just like a simple query
            +let to_insert: i32 = 12345;
            +session.execute(&prepared, (to_insert,)).await?;
            +
            +
            +

            See PreparedStatement API documentation +for more options.

            +
            +

            Note +Prepared statements can be created from Query structs and will inherit from +the custom options that the Query was created with. +This is especially useful when using CachingSession::execute for example.

            +
            +
            +
            +

            Performance

            +

            Prepared queries have good performance, much better than simple queries. +By default they use shard/token aware load balancing.

            +
            +

            Always pass partition key values as bound values. +Otherwise the driver can’t hash them to compute partition key +and they will be sent to the wrong node, which worsens performance.

            +
            +

            Let’s say we have a table like this:

            +
            TABLE ks.prepare_table (
            +    a int,
            +    b int,
            +    c int,
            +    PRIMARY KEY (a, b)
            +)
            +
            +
            +
            use scylla::prepared_statement::PreparedStatement;
            +
            +// WRONG - partition key value is passed in query string
            +// Load balancing will compute the wrong partition key
            +let wrong_prepared: PreparedStatement = session
            +    .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(12345, ?, 16)")
            +    .await?;
            +
            +session.execute(&wrong_prepared, (54321,)).await?;
            +
            +// GOOD - partition key values are sent as bound values
            +// Other values can be sent any way you like, it doesn't matter
            +let good_prepared: PreparedStatement = session
            +    .prepare("INSERT INTO ks.prepare_table (a, b, c) VALUES(?, ?, 16)")
            +    .await?;
            +
            +session.execute(&good_prepared, (12345, 54321)).await?;
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/queries.html b/v0.13.0/queries/queries.html new file mode 100644 index 0000000000..f87170e198 --- /dev/null +++ b/v0.13.0/queries/queries.html @@ -0,0 +1,638 @@ + + + + + + + + + + + + + Making queries | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Making queries

            +

            This driver supports all query types available in Scylla:

            +
              +
            • Simple queries

              +
                +
              • Easy to use

              • +
              • Poor performance

              • +
              • Primitive load balancing

              • +
              +
            • +
            • Prepared queries

              +
                +
              • Need to be prepared before use

              • +
              • Fast

              • +
              • Properly load balanced

              • +
              +
            • +
            • Batch statements

              +
                +
              • Run multiple queries at once

              • +
              • Can be prepared for better performance and load balancing

              • +
              +
            • +
            • Paged queries

              +
                +
              • Allows to read result in multiple pages when it doesn’t fit in a single response

              • +
              • Can be prepared for better performance and load balancing

              • +
              +
            • +
            +

            Additionally there is special functionality to enable USE KEYSPACE queries: +USE keyspace

            +

            Queries are fully asynchronous - you can run as many of them in parallel as you wish.

            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/result.html b/v0.13.0/queries/result.html new file mode 100644 index 0000000000..1d3c6e6ad3 --- /dev/null +++ b/v0.13.0/queries/result.html @@ -0,0 +1,748 @@ + + + + + + + + + + + + + Query result | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Query result

            +

            Session::query and Session::execute return a QueryResult with rows represented as Option<Vec<Row>>.

            +
            +

            Basic representation

            +

            Row is a basic representation of a received row. It can be used by itself, but it’s a bit awkward to use:

            +
            if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
            +    for row in rows {
            +        let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap();
            +    }
            +}
            +
            +
            +
            +
            +

            Parsing using into_typed

            +

            The driver provides a way to parse a row as a tuple of Rust types:

            +
            use scylla::IntoTypedRows;
            +
            +// Parse row as a single column containing an int value
            +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
            +    for row in rows {
            +        let (int_value,): (i32,) = row.into_typed::<(i32,)>()?;
            +    }
            +}
            +
            +// rows.into_typed() converts a Vec of Rows to an iterator of parsing results
            +if let Some(rows) = session.query("SELECT a from ks.tab", &[]).await?.rows {
            +    for row in rows.into_typed::<(i32,)>() {
            +        let (int_value,): (i32,) = row?;
            +    }
            +}
            +
            +// Parse row as two columns containing an int and text columns
            +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
            +    for row in rows.into_typed::<(i32, String)>() {
            +        let (int_value, text_value): (i32, String) = row?;
            +    }
            +}
            +
            +
            +
            +
            +

            Parsing using convenience methods

            +

            QueryResult provides convenience methods for parsing rows. +Here are a few of them:

            +
              +
            • rows_typed::<RowT>() - returns the rows parsed as the given type

            • +
            • maybe_first_row_typed::<RowT> - returns Option<RowT> containing first row from the result

            • +
            • first_row_typed::<RowT> - same as maybe_first_row, but fails without the first row

            • +
            • single_row_typed::<RowT> - same as first_row, but fails when there is more than one row

            • +
            • result_not_rows() - ensures that query response was not rows, helps avoid bugs

            • +
            +
            // Parse row as a single column containing an int value
            +let rows = session
            +    .query("SELECT a from ks.tab", &[])
            +    .await?
            +    .rows_typed::<(i32,)>()?; // Same as .rows()?.into_typed()
            +for row in rows {
            +    let (int_value,): (i32,) = row?;
            +}
            +
            +// maybe_first_row_typed gets the first row and parses it as the given type
            +let first_int_val: Option<(i32,)> = session
            +    .query("SELECT a from ks.tab", &[])
            +    .await?
            +    .maybe_first_row_typed::<(i32,)>()?;
            +
            +// no_rows fails when the response is rows
            +session.query("INSERT INTO ks.tab (a) VALUES (0)", &[]).await?.result_not_rows()?;
            +
            +
            +

            For more see QueryResult

            +
            +

            NULL values

            +

            NULL values will return an error when parsed as a Rust type. +To properly handle NULL values parse column as an Option<>:

            +
            use scylla::IntoTypedRows;
            +
            +// Parse row as two columns containing an int and text which might be null
            +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
            +    for row in rows.into_typed::<(i32, Option<String>)>() {
            +        let (int_value, str_or_null): (i32, Option<String>) = row?;
            +    }
            +}
            +
            +
            +
            +
            +

            Parsing row as a custom struct

            +

            It is possible to receive row as a struct with fields matching the columns.
            +The struct must:

            +
              +
            • have the same number of fields as the number of queried columns

            • +
            • have field types matching the columns being received

            • +
            • derive FromRow

            • +
            +

            Field names don’t need to match column names.

            +
            use scylla::IntoTypedRows;
            +use scylla::macros::FromRow;
            +use scylla::frame::response::cql_to_rust::FromRow;
            +
            +#[derive(FromRow)]
            +struct MyRow {
            +    age: i32,
            +    name: Option<String>
            +}
            +
            +// Parse row as two columns containing an int and text which might be null
            +if let Some(rows) = session.query("SELECT a, b from ks.tab", &[]).await?.rows {
            +    for row in rows.into_typed::<MyRow>() {
            +        let my_row: MyRow = row?;
            +    }
            +}
            +
            +
            +
            +
            +

            Other data types

            +

            For parsing other data types see Data Types

            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/schema-agreement.html b/v0.13.0/queries/schema-agreement.html new file mode 100644 index 0000000000..449d47f7ba --- /dev/null +++ b/v0.13.0/queries/schema-agreement.html @@ -0,0 +1,671 @@ + + + + + + + + + + + + + Schema agreement | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Schema agreement

            +

            Sometimes after performing queries some nodes have not been updated, so we need a mechanism that checks if every node have agreed on schema version.

            +
            +

            Automated awaiting schema agreement

            +

            The driver automatically awaits schema agreement after a schema-altering query is executed. +Waiting for schema agreement more than necessary is never a bug, but might slow down applications which do a lot of schema changes (e.g. a migration). +For instance, in case where somebody wishes to create a keyspace and then a lot of tables in it, it makes sense only to wait after creating a keyspace +and after creating all the tables rather than after every query. Therefore, the said behaviour can be disabled:

            +
            let session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .auto_await_schema_agreement(false)
            +    .build()
            +    .await?;
            +
            +
            +
            +
            +

            Manually awaiting schema agreement

            +

            Session::await_schema_agreement returns a Future that can be awaited as long as schema is not in an agreement. +However, it won’t wait forever; SessionConfig defines a timeout that limits the time of waiting. If the timeout elapses, +the return value is Err(QueryError::RequestTimeout), otherwise it is Ok(schema_version).

            +
            session.await_schema_agreement().await?;
            +
            +
            +
            +
            +

            Interval of checking for schema agreement

            +

            If the schema is not agreed upon, the driver sleeps for a duration before checking it again. The default value is 200 milliseconds, +but it can be changed with SessionBuilder::schema_agreement_interval.

            +
            SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .schema_agreement_interval(Duration::from_secs(1))
            +    .build()
            +    .await?;
            +
            +
            +
            +
            +

            Checking if schema is in agreement now

            +

            If you want to check if schema is in agreement now, without retrying after failure, you can use Session::check_schema_agreement function.

            +
            if session.check_schema_agreement().await?.is_some() {
            +    println!("SCHEMA AGREED");
            +} else {
            +    println!("SCHEMA IS NOT IN AGREEMENT");
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/simple.html b/v0.13.0/queries/simple.html new file mode 100644 index 0000000000..83006ffb99 --- /dev/null +++ b/v0.13.0/queries/simple.html @@ -0,0 +1,708 @@ + + + + + + + + + + + + + Simple query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Simple query

            +

            Simple query takes query text and values and simply executes them on a Session:

            +
            // Insert a value into the table
            +let to_insert: i32 = 12345;
            +session
            +    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
            +    .await?;
            +
            +
            +
            +

            Warning
            +Don’t use simple query to receive large amounts of data.
            +By default the query is unpaged and might cause heavy load on the cluster.
            +In such cases set a page size and use paged query instead.\

            +

            When page size is set, query will return only the first page of results.

            +
            +
            +

            Warning
            +If the values are not empty, driver first needs to send a PREPARE request +in order to fetch information required to serialize values. This will affect +performance because 2 round trips will be required instead of 1.

            +
            +
            +

            First argument - the query

            +

            As the first argument Session::query takes anything implementing Into<Query>.
            +You can create a query manually to set custom options. For example to change query consistency:

            +
            use scylla::query::Query;
            +use scylla::statement::Consistency;
            +
            +// Create a Query manually to change the Consistency to ONE
            +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
            +my_query.set_consistency(Consistency::One);
            +
            +// Insert a value into the table
            +let to_insert: i32 = 12345;
            +session.query(my_query, (to_insert,)).await?;
            +
            +
            +

            See Query API documentation for more options

            +
            +
            +

            Second argument - the values

            +

            Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.
            +Each ? in query text will be filled with the matching value.

            +

            The easiest way is to pass values using a tuple:

            +
            // Sending an integer and a string using a tuple
            +session
            +    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, 'text2')", (2_i32, "Some text"))
            +    .await?;
            +
            +
            +

            Here the first ? will be filled with 2 and the second with "Some text".

            +
            +

            Never pass values by adding strings, this could lead to SQL Injection

            +
            +

            See Query values for more information about sending values in queries

            +
            +
            +

            Query result

            +

            Session::query returns QueryResult with rows represented as Option<Vec<Row>>.
            +Each row can be parsed as a tuple of rust types using rows_typed:

            +
            use scylla::IntoTypedRows;
            +
            +// Query rows from the table and print them
            +let result = session.query("SELECT a FROM ks.tab", &[]).await?;
            +let mut iter = result.rows_typed::<(i32,)>()?;
            +while let Some(read_row) = iter.next().transpose()? {
            +    println!("Read a value from row: {}", read_row.0);
            +}
            +
            +
            +
            +

            In cases where page size is set, simple query returns only a single page of results.
            +To receive all pages use a paged query instead.\

            +
            +

            See Query result for more information about handling query results

            +
            +
            +

            Performance

            +

            Simple queries should not be used in places where performance matters.
            +If performance matters use a Prepared query instead.

            +

            With simple query the database has to parse query text each time it’s executed, which worsens performance.\

            +

            Additionally token and shard aware load balancing does not work with simple queries. They are sent to random nodes.

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/timeouts.html b/v0.13.0/queries/timeouts.html new file mode 100644 index 0000000000..9500a345f8 --- /dev/null +++ b/v0.13.0/queries/timeouts.html @@ -0,0 +1,657 @@ + + + + + + + + + + + + + Query timeouts | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Query timeouts

            +

            Query execution time can be limited by setting a request timeout. If a query does not complete +in the given time, then QueryError::RequestTimeout is returned by the driver immediately, +so that application logic can continue operating, but the query may still be in progress on the server.

            +

            As a side note, if one wishes custom server-side timeouts (i.e. actual interruption of query processing), +one can use aUSING TIMEOUT <duration> directive supported in ScyllaDB +(but not in Cassandra).

            +

            Timeout can be set globally (per session) or locally (for given statement). +The default per-session timeout is currently 30s. +It is possible to turn off timeouts completely by providing None as timeout when building Session. +However, setting per-statement timeout to None results in falling back to per-session timeout.

            +
            use scylla::{Session, SessionBuilder, query::Query};
            +use scylla::transport::ExecutionProfile;
            +use std::time::Duration;
            +
            +let uri = std::env::var("SCYLLA_URI")
            +    .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
            +
            +let no_timeout_profile_handle = ExecutionProfile::builder()
            +    .request_timeout(None) // no timeout
            +    .build()
            +    .into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node(uri)
            +    .default_execution_profile_handle(no_timeout_profile_handle) // no per-session timeout
            +    .build()
            +    .await?;
            +
            +// This query, having no timeout, could block indefinitely if a queried node hangs.
            +session
            +    .query("TRUNCATE keyspace.table", ())
            +    .await?;
            +
            +let three_sec_timeout_profile_handle = ExecutionProfile::builder()
            +    .request_timeout(Some(Duration::from_secs(3))) // no timeout
            +    .build()
            +    .into_handle();
            +
            +// The below query will last for no more than 3 seconds, yielding a RequestTimeout error
            +// if no response arrives until then.
            +let mut query: Query = "TRUNCATE keyspace.table".into();
            +query.set_execution_profile_handle(Some(three_sec_timeout_profile_handle));
            +session
            +    .query(query, ())
            +    .await?;
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/usekeyspace.html b/v0.13.0/queries/usekeyspace.html new file mode 100644 index 0000000000..49e9838f7a --- /dev/null +++ b/v0.13.0/queries/usekeyspace.html @@ -0,0 +1,691 @@ + + + + + + + + + + + + + USE keyspace | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            USE keyspace

            +

            Using a keyspace allows to omit keyspace name in queries.

            +

            For example in cqlsh one could write:

            +
            cqlsh> SELECT * FROM my_keyspace.table;
            +
            + a     | b     |
            +-------+-------+
            + 12345 | 54321 |
            +
            +(1 rows)
            +cqlsh> USE my_keyspace;
            +cqlsh:my_keyspace> SELECT * FROM table;
            +
            + a     | b     |
            +-------+-------+
            + 12345 | 54321 |
            +
            +(1 rows)
            +
            +
            +

            Tables from other keyspaces can still easily be accessed by using their keyspace names.

            +
            cqlsh:my_keyspace> SELECT * FROM other_keyspace.other_table;
            +
            +
            +

            In the driver this can be achieved using Session::use_keyspace:

            +
            session
            +    .query("INSERT INTO my_keyspace.tab (a) VALUES ('test1')", &[])
            +    .await?;
            +
            +session.use_keyspace("my_keyspace", false).await?;
            +
            +// Now we can omit keyspace name in the query
            +session
            +    .query("INSERT INTO tab (a) VALUES ('test2')", &[])
            +    .await?;
            +
            +
            +

            The first argument is the keyspace name.
            +The second argument states whether this name is case sensitive.

            +

            It is also possible to send raw use keyspace query using Session::query instead of Session::use_keyspace such as:

            +
            session.query("USE my_keyspace", &[]).await?;
            +
            +
            +

            This method has a slightly worse latency than Session::use_keyspace - there are two roundtrips needed instead of one. +Therefore, Session::use_keyspace is the preferred method for setting keyspaces.

            +
            +

            Multiple use queries at once

            +

            Don’t run multiple use_keyspace queries at once. +This could end up with half of connections using one keyspace and the other half using the other.

            +
            +
            +

            Case sensitivity

            +

            In CQL a keyspace name can be case insensitive (without ") or case sensitive (with ").
            +If the second argument to use_keyspace is set to true this keyspace name will be wrapped in ".
            +It is best to avoid the problem altogether and just not create two keyspaces with the same name but different cases.

            +

            Let’s see what happens when there are two keyspaces with the same name but different cases: my_keyspace and MY_KEYSPACE:

            +
            // lowercase name without case sensitivity will use my_keyspace
            +session.use_keyspace("my_keyspace", false).await?;
            +
            +// lowercase name with case sensitivity will use my_keyspace
            +session.use_keyspace("my_keyspace", true).await?;
            +
            +// uppercase name without case sensitivity will use my_keyspace
            +session.use_keyspace("MY_KEYSPACE", false).await?;
            +
            +// uppercase name with case sensitivity will use MY_KEYSPACE
            +session.use_keyspace("MY_KEYSPACE", true).await?;
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/queries/values.html b/v0.13.0/queries/values.html new file mode 100644 index 0000000000..8de34d4bbc --- /dev/null +++ b/v0.13.0/queries/values.html @@ -0,0 +1,747 @@ + + + + + + + + + + + + + Query values | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Query values

            +

            Query text is constant, but the values might change. +You can pass changing values to a query by specifying a list of variables as bound values.
            +Each ? in query text will be filled with the matching value.

            +
            +

            Never pass values by adding strings, this could lead to SQL Injection

            +
            +

            Each list of values to send in a query must implement the trait SerializeRow.
            +By default this can be a slice &[], a tuple () (max 16 elements) of values to send, +or a custom struct which derives from SerializeRow.

            +

            A few examples:

            +
            // Empty slice means that there are no values to send
            +session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?;
            +
            +// Empty tuple/unit also means that there are no values to send
            +session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?;
            +
            +// Sending three integers using a slice:
            +session
            +    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref())
            +    .await?;
            +
            +// Sending an integer and a string using a tuple
            +session
            +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text"))
            +    .await?;
            +
            +// Sending an integer and a string using a named struct.
            +// Names of fields must match names of columns in request,
            +// but having them in the same order is not required.
            +// If the fields are in the same order, you can use attribute:
            +// `#[scylla(flavor = "enforce_order")]`
            +// in order to skip sorting the fields and just check if they
            +// are in the same order. See documentation of this macro
            +// for more information.
            +#[derive(SerializeRow)]
            +struct IntString {
            +    a: i32,
            +    b: String,
            +}
            +
            +let int_string = IntString {
            +    a: 42_i32,
            +    b: "hello".to_owned(),
            +};
            +
            +session
            +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string)
            +    .await?;
            +
            +// You can use named bind markers in query if you want
            +// your names in struct to be different than column names.
            +#[derive(SerializeRow)]
            +struct IntStringCustom {
            +    first_value: i32,
            +    second_value: String,
            +}
            +
            +let int_string_custom = IntStringCustom {
            +    first_value: 42_i32,
            +    second_value: "hello".to_owned(),
            +};
            +
            +session
            +    .query("INSERT INTO ks.tab (a, b) VALUES(:first_value, :second_value)", int_string_custom)
            +    .await?;
            +
            +// Sending a single value as a tuple requires a trailing coma (Rust syntax):
            +session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?;
            +
            +// Each value can also be sent using a reference:
            +session
            +    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text"))
            +    .await?;
            +
            +// A map of named values can also be provided:
            +let mut vals: HashMap<&str, CqlValue> = HashMap::new();
            +vals.insert("avalue", CqlValue::Text("hello".to_string()));
            +vals.insert("bvalue", CqlValue::Int(17));
            +session
            +    .query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals)
            +    .await?;
            +
            +
            +
            +

            NULL values

            +

            Null values can be sent using Option<> - sending a None will make the value NULL:

            +
            let null_i32: Option<i32> = None;
            +session
            +    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
            +    .await?;
            +
            +
            +
            +
            +

            Unset values

            +

            When performing an insert with values which might be NULL, it’s better to use Unset.
            +Database treats inserting NULL as a delete operation and will generate a tombstone. +Using Unset results in better performance:

            +
            use scylla::frame::value::{MaybeUnset, Unset};
            +
            +// Inserting a null results in suboptimal performance
            +let null_i32: Option<i32> = None;
            +session
            +    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
            +    .await?;
            +
            +// Using MaybeUnset enum is better
            +let unset_i32: MaybeUnset<i32> = MaybeUnset::Unset;
            +session
            +    .query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,))
            +    .await?;
            +
            +// If we are sure that a value should be unset we can simply use Unset
            +session
            +    .query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,))
            +    .await?;
            +
            +
            +

            See the issue for more information about Unset

            +
            +
            +

            Other data types

            +

            See Data Types for instructions on sending other data types

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/quickstart/create-project.html b/v0.13.0/quickstart/create-project.html new file mode 100644 index 0000000000..80442b952f --- /dev/null +++ b/v0.13.0/quickstart/create-project.html @@ -0,0 +1,639 @@ + + + + + + + + + + + + + Creating a project | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Creating a project

            +

            To create a new project run:

            +
            cargo new myproject
            +
            +
            +

            In Cargo.toml add useful dependencies:

            +
            [dependencies]
            +scylla = "0.13"
            +tokio = { version = "1.12", features = ["full"] }
            +futures = "0.3.6"
            +uuid = "1.0"
            +bigdecimal = "0.4"
            +num-bigint = "0.3"
            +tracing = "0.1.36"
            +tracing-subscriber = { version = "0.3.14", features = ["env-filter"] }
            +
            +
            +

            In main.rs put:

            +
            use scylla::Session;
            +
            +#[tokio::main]
            +async fn main() {
            +    println!("Hello scylla!");
            +}
            +
            +
            +

            Now running cargo run should print:

            +
            Hello scylla!
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/quickstart/example.html b/v0.13.0/quickstart/example.html new file mode 100644 index 0000000000..b2de22ffaa --- /dev/null +++ b/v0.13.0/quickstart/example.html @@ -0,0 +1,660 @@ + + + + + + + + + + + + + Connecting and running a simple query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Connecting and running a simple query

            +

            Now everything is ready to use the driver. +Here is a small example:

            +
            use scylla::{IntoTypedRows, Session, SessionBuilder};
            +use std::error::Error;
            +
            +#[tokio::main]
            +async fn main() -> Result<(), Box<dyn Error>> {
            +    // Create a new Session which connects to node at 127.0.0.1:9042
            +    // (or SCYLLA_URI if specified)
            +    let uri = std::env::var("SCYLLA_URI")
            +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
            +
            +    let session: Session = SessionBuilder::new()
            +        .known_node(uri)
            +        .build()
            +        .await?;
            +
            +    // Create an example keyspace and table
            +    session
            +        .query(
            +            "CREATE KEYSPACE IF NOT EXISTS ks WITH REPLICATION = \
            +            {'class' : 'NetworkTopologyStrategy', 'replication_factor' : 1}",
            +            &[],
            +        )
            +        .await?;
            +
            +    session
            +        .query(
            +            "CREATE TABLE IF NOT EXISTS ks.extab (a int primary key)",
            +            &[],
            +        )
            +        .await?;
            +
            +    // Insert a value into the table
            +    let to_insert: i32 = 12345;
            +    session
            +        .query("INSERT INTO ks.extab (a) VALUES(?)", (to_insert,))
            +        .await?;
            +
            +    // Query rows from the table and print them
            +    let result = session.query("SELECT a FROM ks.extab", &[]).await?;
            +    let mut iter = result.rows_typed::<(i32,)>()?;
            +    while let Some(read_row) = iter.next().transpose()? {
            +        println!("Read a value from row: {}", read_row.0);
            +    }
            +
            +    Ok(())
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/quickstart/quickstart.html b/v0.13.0/quickstart/quickstart.html new file mode 100644 index 0000000000..1e54a1cc72 --- /dev/null +++ b/v0.13.0/quickstart/quickstart.html @@ -0,0 +1,613 @@ + + + + + + + + + + + + + Quick Start | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Quick Start

            +

            In this chapter we will set up a Rust project and run a few simple queries.

            +

            Topics Include:

            + +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/quickstart/scylla-docker.html b/v0.13.0/quickstart/scylla-docker.html new file mode 100644 index 0000000000..51a5f4099d --- /dev/null +++ b/v0.13.0/quickstart/scylla-docker.html @@ -0,0 +1,642 @@ + + + + + + + + + + + + + Running Scylla using Docker | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Running Scylla using Docker

            +

            To make queries we will need a running Scylla instance. The easiest way is to use a Docker image.
            +Please install Docker if it’s not installed.

            +
            +

            Running scylla

            +

            To start Scylla run:

            +
            # on Linux sudo might be required
            +docker run --rm -it -p 9042:9042 scylladb/scylla --smp 2
            +
            +
            +

            Docker will download the image, then after minute or two there should be a message like:

            +
            Starting listening for CQL clients on 172.17.0.2:9042
            +
            +
            +

            This means that Scylla is ready to receive queries

            +

            To stop this instance press Ctrl + C

            +
            +
            +

            More information

            +

            More information about this image can be found on dockerhub

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/retry-policy/default.html b/v0.13.0/retry-policy/default.html new file mode 100644 index 0000000000..91f7e90682 --- /dev/null +++ b/v0.13.0/retry-policy/default.html @@ -0,0 +1,688 @@ + + + + + + + + + + + + + Default retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Default retry policy

            +

            This is the retry policy used by default. It retries when there is a high chance that it might help.
            +This policy is based on the one in DataStax Java Driver. +The behaviour is the same.

            +
            +

            Examples

            +

            To use in Session:

            +
            use scylla::{Session, SessionBuilder};
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::retry_policy::DefaultRetryPolicy;
            +
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .default_execution_profile_handle(handle)
            +    .build()
            +    .await?;
            +
            +
            +

            To use in a simple query:

            +
            use scylla::query::Query;
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::retry_policy::DefaultRetryPolicy;
            +
            +// Create a Query manually and set the retry policy
            +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
            +my_query.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new())));
            +
            +// You can also set retry policy in an execution profile
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +my_query.set_execution_profile_handle(Some(handle));
            +
            +// Run the query using this retry policy
            +let to_insert: i32 = 12345;
            +session.query(my_query, (to_insert,)).await?;
            +
            +
            +

            To use in a prepared query:

            +
            use scylla::prepared_statement::PreparedStatement;
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::retry_policy::DefaultRetryPolicy;
            +
            +// Create PreparedStatement manually and set the retry policy
            +let mut prepared: PreparedStatement = session
            +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
            +    .await?;
            +prepared.set_retry_policy(Some(Arc::new(DefaultRetryPolicy::new())));
            +
            +// You can also set retry policy in an execution profile
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(DefaultRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +prepared.set_execution_profile_handle(Some(handle));
            +
            +// Run the query using this retry policy
            +let to_insert: i32 = 12345;
            +session.execute(&prepared, (to_insert,)).await?;
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/retry-policy/downgrading-consistency.html b/v0.13.0/retry-policy/downgrading-consistency.html new file mode 100644 index 0000000000..13e1180c04 --- /dev/null +++ b/v0.13.0/retry-policy/downgrading-consistency.html @@ -0,0 +1,729 @@ + + + + + + + + + + + + + Downgrading consistency retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Downgrading consistency retry policy

            +

            A retry policy that sometimes retries with a lower consistency level than the one initially +requested. +BEWARE: this policy may retry queries using a lower consistency level than the one +initially requested. By doing so, it may break consistency guarantees. In other words, if you use +this retry policy, there are cases (documented below) where a read at Consistency::Quorum may +not see a preceding write at Consistency::Quorum. Do not use this policy unless you have +understood the cases where this can happen and are ok with that. It is also highly recommended to +always log the occurrences of such consistency breaks. +This policy implements the same retries than the DefaultRetryPolicy policy. But on top +of that, it also retries in the following cases:

            +
              +
            • On a read timeout: if the number of replicas that responded is greater than one, but lower +than is required by the requested consistency level, the operation is retried at a lower +consistency level.

            • +
            • On a write timeout: if the operation is a WriteType::UnloggedBatch and at least one +replica acknowledged the write, the operation is retried at a lower consistency level. +Furthermore, for other operations, if at least one replica acknowledged the write, the +timeout is ignored.

            • +
            • On an unavailable exception: if at least one replica is alive, the operation is retried at +a lower consistency level.

            • +
            +

            The lower consistency level to use for retries is determined by the following rules:

            +
              +
            • if more than 3 replicas responded, use Consistency::Three.

            • +
            • if 1, 2 or 3 replicas responded, use the corresponding level Consistency::One, Consistency::Two or +Consistency::Three.

            • +
            +

            Note that if the initial consistency level was Consistency::EachQuorum, Scylla returns the number +of live replicas in the datacenter that failed to reach consistency, not the overall +number in the cluster. Therefore if this number is 0, we still retry at Consistency::One, on the +assumption that a host may still be up in another datacenter. +The reasoning being this retry policy is the following one. If, based on the information the +Scylla coordinator node returns, retrying the operation with the initially requested +consistency has a chance to succeed, do it. Otherwise, if based on this information we know +the initially requested consistency level cannot be achieved currently, then:

            +
              +
            • For writes, ignore the exception (thus silently failing the consistency requirement) if we +know the write has been persisted on at least one replica.

            • +
            • For reads, try reading at a lower consistency level (thus silently failing the consistency +requirement). +In other words, this policy implements the idea that if the requested consistency level cannot be +achieved, the next best thing for writes is to make sure the data is persisted, and that reading +something is better than reading nothing, even if there is a risk of reading stale data.

            • +
            +

            This policy is based on the one in DataStax Java Driver. +The behaviour is the same.

            +
            +

            Examples

            +

            To use in Session:

            +
            use scylla::{Session, SessionBuilder};
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
            +
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .default_execution_profile_handle(handle)
            +    .build()
            +    .await?;
            +
            +
            +

            To use in a simple query:

            +
            use scylla::query::Query;
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
            +
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +
            +// Create a Query manually and set the retry policy
            +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
            +my_query.set_execution_profile_handle(Some(handle));
            +
            +// Run the query using this retry policy
            +let to_insert: i32 = 12345;
            +session.query(my_query, (to_insert,)).await?;
            +
            +
            +

            To use in a prepared query:

            +
            use scylla::prepared_statement::PreparedStatement;
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::downgrading_consistency_retry_policy::DowngradingConsistencyRetryPolicy;
            +
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(DowngradingConsistencyRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +
            +// Create PreparedStatement manually and set the retry policy
            +let mut prepared: PreparedStatement = session
            +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
            +    .await?;
            +
            +prepared.set_execution_profile_handle(Some(handle));
            +
            +
            +// Run the query using this retry policy
            +let to_insert: i32 = 12345;
            +session.execute(&prepared, (to_insert,)).await?;
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/retry-policy/fallthrough.html b/v0.13.0/retry-policy/fallthrough.html new file mode 100644 index 0000000000..71a81f8d2b --- /dev/null +++ b/v0.13.0/retry-policy/fallthrough.html @@ -0,0 +1,683 @@ + + + + + + + + + + + + + Fallthrough retry policy | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Fallthrough retry policy

            +

            The FalthroughRetryPolicy never retries, returns errors straight to the user. Useful for debugging.

            +
            +

            Examples

            +

            To use in Session:

            +
            use scylla::{Session, SessionBuilder};
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::retry_policy::FallthroughRetryPolicy;
            +
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .default_execution_profile_handle(handle)
            +    .build()
            +    .await?;
            +
            +
            +

            To use in a simple query:

            +
            use scylla::query::Query;
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::retry_policy::FallthroughRetryPolicy;
            +
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +
            +// Create a Query manually and set the retry policy
            +let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
            +my_query.set_execution_profile_handle(Some(handle));
            +
            +// Run the query using this retry policy
            +let to_insert: i32 = 12345;
            +session.query(my_query, (to_insert,)).await?;
            +
            +
            +

            To use in a prepared query:

            +
            use scylla::prepared_statement::PreparedStatement;
            +use scylla::transport::ExecutionProfile;
            +use scylla::transport::retry_policy::FallthroughRetryPolicy;
            +
            +let handle = ExecutionProfile::builder()
            +    .retry_policy(Box::new(FallthroughRetryPolicy::new()))
            +    .build()
            +    .into_handle();
            +
            +// Create PreparedStatement manually and set the retry policy
            +let mut prepared: PreparedStatement = session
            +    .prepare("INSERT INTO ks.tab (a) VALUES(?)")
            +    .await?;
            +
            +prepared.set_execution_profile_handle(Some(handle));
            +
            +// Run the query using this retry policy
            +let to_insert: i32 = 12345;
            +session.execute(&prepared, (to_insert,)).await?;
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/retry-policy/retry-policy.html b/v0.13.0/retry-policy/retry-policy.html new file mode 100644 index 0000000000..8e36f8a7bb --- /dev/null +++ b/v0.13.0/retry-policy/retry-policy.html @@ -0,0 +1,654 @@ + + + + + + + + + + + + + Retry policy configuration | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Retry policy configuration

            +

            After a query fails the driver might decide to retry it based on its Retry Policy and the query itself. +Retry policy can be configured for Session or just for a single query.

            +
            +

            Retry policies

            +

            By default there are three retry policies:

            + +

            It’s possible to implement a custom Retry Policy by implementing the traits RetryPolicy and RetrySession.

            +
            +
            +

            Query idempotence

            +

            A query is idempotent if it can be applied multiple times without changing the result of the initial application

            +

            Specifying that a query is idempotent increases the chances that it will be retried in case of failure. +Idempotent queries can be retried in situations where retrying non idempotent queries would be dangerous.

            +

            Idempotence has to be specified manually, the driver is not able to figure it out by itself.

            +
            use scylla::query::Query;
            +use scylla::prepared_statement::PreparedStatement;
            +
            +// Specify that a Query is idempotent
            +let mut my_query: Query = Query::new("SELECT a FROM ks.tab");
            +my_query.set_is_idempotent(true);
            +
            +
            +// Specify that a PreparedStatement is idempotent
            +let mut prepared: PreparedStatement = session
            +    .prepare("SELECT a FROM ks.tab")
            +    .await?;
            +
            +prepared.set_is_idempotent(true);
            +
            +
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/schema/schema.html b/v0.13.0/schema/schema.html new file mode 100644 index 0000000000..5aef2cb677 --- /dev/null +++ b/v0.13.0/schema/schema.html @@ -0,0 +1,669 @@ + + + + + + + + + + + + + Schema | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + +
            +

            Schema

            +

            The driver is capable of fetching database schema and presenting it to its users.

            +
            +

            Fetching schema

            +

            Fetching database schema occurs periodically, but it can also be done on-demand. In order to fetch the newest database schema, one can call refresh_metadata() on a Session instance:

            +
            #[tokio::main]
            +async fn main() -> Result<(), Box<dyn Error>> {
            +    let uri = std::env::var("SCYLLA_URI")
            +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
            +
            +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
            +    // Schema metadata will be fetched below
            +    session.refresh_metadata().await?;
            +    Ok(())
            +}
            +
            +
            +
            +
            +

            Inspecting schema

            +

            Once fetched, a snapshot of cluster’s schema can be examined. The following information can be obtained:

            +
              +
            • keyspace

              +
                +
              • tables belonging to the keyspace

              • +
              • materialized views belonging to the keyspace

              • +
              • replication strategy

              • +
              • user-defined types

              • +
              +
            • +
            • table/view

              +
                +
              • primary key definition

              • +
              • columns

              • +
              • partitioner type

              • +
              +
            • +
            +

            Example showing how to print obtained schema information:

            +
            #[tokio::main]
            +async fn main() -> Result<(), Box<dyn Error>> {
            +    let uri = std::env::var("SCYLLA_URI")
            +        .unwrap_or_else(|_| "127.0.0.1:9042".to_string());
            +
            +    let session: Session = SessionBuilder::new().known_node(uri).build().await?;
            +    // Schema metadata will be fetched below
            +    session.refresh_metadata().await?;
            +
            +    let cluster_data = &session.get_cluster_data();
            +    let keyspaces = &cluster_data.get_keyspace_info();
            +
            +    for (keyspace_name, keyspace_info) in keyspaces.iter() {
            +        println!("Keyspace {}:", keyspace_name);
            +        println!("\tTables: {:#?}", keyspace_info.tables);
            +        println!("\tViews: {:#?}", keyspace_info.views);
            +        println!("\tUDTs: {:#?}", keyspace_info.user_defined_types);
            +    }
            +
            +    Ok(())
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/search.html b/v0.13.0/search.html new file mode 100644 index 0000000000..b8e4c6d401 --- /dev/null +++ b/v0.13.0/search.html @@ -0,0 +1,588 @@ + + + + + + + + + + + + + Search | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + + + + + +
            + + + + + +
            + + +
            + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/searchindex.js b/v0.13.0/searchindex.js new file mode 100644 index 0000000000..7abe38f4fc --- /dev/null +++ b/v0.13.0/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["connecting/authentication", "connecting/compression", "connecting/connecting", "connecting/tls", "contents", "data-types/blob", "data-types/collections", "data-types/counter", "data-types/data-types", "data-types/date", "data-types/decimal", "data-types/duration", "data-types/inet", "data-types/primitive", "data-types/text", "data-types/time", "data-types/timestamp", "data-types/timeuuid", "data-types/tuple", "data-types/udt", "data-types/uuid", "data-types/varint", "execution-profiles/create-and-use", "execution-profiles/execution-profiles", "execution-profiles/maximal-example", "execution-profiles/priority", "execution-profiles/remap", "index", "load-balancing/default-policy", "load-balancing/load-balancing", "logging/logging", "metrics/metrics", "migration-guides/0.11-serialization", "migration-guides/migration-guides", "queries/batch", "queries/lwt", "queries/paged", "queries/prepared", "queries/queries", "queries/result", "queries/schema-agreement", "queries/simple", "queries/timeouts", "queries/usekeyspace", "queries/values", "quickstart/create-project", "quickstart/example", "quickstart/quickstart", "quickstart/scylla-docker", "retry-policy/default", "retry-policy/downgrading-consistency", "retry-policy/fallthrough", "retry-policy/retry-policy", "schema/schema", "speculative-execution/percentile", "speculative-execution/simple", "speculative-execution/speculative", "tracing/basic", "tracing/paged", "tracing/prepare", "tracing/query-history", "tracing/tracing"], "filenames": ["connecting/authentication.md", "connecting/compression.md", "connecting/connecting.md", "connecting/tls.md", "contents.rst", "data-types/blob.md", "data-types/collections.md", "data-types/counter.md", "data-types/data-types.md", "data-types/date.md", "data-types/decimal.md", "data-types/duration.md", "data-types/inet.md", "data-types/primitive.md", "data-types/text.md", "data-types/time.md", "data-types/timestamp.md", "data-types/timeuuid.md", "data-types/tuple.md", "data-types/udt.md", "data-types/uuid.md", "data-types/varint.md", "execution-profiles/create-and-use.md", "execution-profiles/execution-profiles.md", "execution-profiles/maximal-example.md", "execution-profiles/priority.md", "execution-profiles/remap.md", "index.md", "load-balancing/default-policy.md", "load-balancing/load-balancing.md", "logging/logging.md", "metrics/metrics.md", "migration-guides/0.11-serialization.md", "migration-guides/migration-guides.md", "queries/batch.md", "queries/lwt.md", "queries/paged.md", "queries/prepared.md", "queries/queries.md", "queries/result.md", "queries/schema-agreement.md", "queries/simple.md", "queries/timeouts.md", "queries/usekeyspace.md", "queries/values.md", "quickstart/create-project.md", "quickstart/example.md", "quickstart/quickstart.md", "quickstart/scylla-docker.md", "retry-policy/default.md", "retry-policy/downgrading-consistency.md", "retry-policy/fallthrough.md", "retry-policy/retry-policy.md", "schema/schema.md", "speculative-execution/percentile.md", "speculative-execution/simple.md", "speculative-execution/speculative.md", "tracing/basic.md", "tracing/paged.md", "tracing/prepare.md", "tracing/query-history.md", "tracing/tracing.md"], "titles": ["Authentication", "Compression", "Connecting to the cluster", "TLS", "<no title>", "Blob", "List, Set, Map", "Counter", "Data Types", "Date", "Decimal", "Duration", "Inet", "Bool, Tinyint, Smallint, Int, Bigint, Float, Double", "Ascii, Text, Varchar", "Time", "Timestamp", "Timeuuid", "Tuple", "User defined types", "Uuid", "Varint", "Creating a profile and setting it", "Execution profiles", "All options supported by a profile", "Priorities of execution settings", "Remapping execution profile handles", "Scylla Rust Driver", "DefaultPolicy", "Load balancing", "Logging", "Driver metrics", "Adjusting code to changes in serialization API introduced in 0.11", "Migration guides", "Batch statement", "Lightweight transaction (LWT) query", "Paged query", "Prepared query", "Making queries", "Query result", "Schema agreement", "Simple query", "Query timeouts", "USE keyspace", "Query values", "Creating a project", "Connecting and running a simple query", "Quick Start", "Running Scylla using Docker", "Default retry policy", "Downgrading consistency retry policy", "Fallthrough retry policy", "Retry policy configuration", "Schema", "Percentile speculative execution", "Simple speculative execution", "Speculative execution", "Tracing a simple/prepared/batch query", "Tracing a paged query", "Tracing Session::prepare", "Query Execution History", "Query tracing"], "terms": {"driver": [0, 1, 2, 3, 8, 19, 28, 29, 30, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 49, 50, 52, 53, 56, 61], "support": [0, 1, 2, 3, 9, 15, 16, 21, 28, 32, 38, 42, 61], "both": [0, 32], "usernam": [0, 2], "password": [0, 2], "defin": [0, 8, 26, 32, 35, 40, 53], "user": [0, 8, 10, 21, 28, 32, 51, 52, 53], "To": [0, 3, 10, 19, 21, 22, 28, 29, 30, 32, 37, 39, 41, 45, 48, 49, 50, 51, 54, 55, 60], "specifi": [0, 1, 2, 25, 28, 34, 37, 41, 44, 46, 52, 60], "method": [0, 2, 28, 29, 32, 43, 56], "sessionbuild": [0, 1, 2, 3, 22, 25, 26, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "scylla": [0, 1, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 32, 34, 35, 36, 37, 38, 39, 41, 42, 44, 45, 46, 47, 49, 50, 51, 52, 54, 55, 57, 58, 59, 60, 61], "session": [0, 1, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26, 29, 30, 31, 32, 34, 35, 36, 39, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61], "let": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 30, 31, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "new": [0, 1, 2, 3, 6, 12, 16, 22, 24, 25, 26, 28, 29, 30, 34, 35, 36, 40, 41, 42, 44, 45, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "known_nod": [0, 1, 2, 3, 22, 25, 26, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "127": [0, 1, 2, 3, 12, 22, 25, 26, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55, 60], "0": [0, 1, 2, 3, 7, 10, 12, 13, 16, 18, 22, 25, 26, 30, 33, 39, 40, 41, 42, 45, 46, 48, 49, 50, 51, 53, 54, 55, 60], "1": [0, 1, 2, 3, 5, 6, 9, 11, 12, 15, 16, 18, 22, 25, 26, 28, 30, 32, 34, 36, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 53, 54, 55, 60], "9042": [0, 1, 2, 22, 25, 26, 30, 40, 42, 46, 48, 49, 50, 51, 53, 54, 55, 60], "myusernam": 0, "mypassword": 0, "build": [0, 1, 2, 3, 22, 24, 25, 26, 28, 29, 30, 40, 42, 46, 49, 50, 51, 53, 54, 55], "await": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 29, 30, 34, 35, 36, 37, 39, 41, 42, 43, 44, 46, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60], "A": [0, 32, 34, 35, 44, 50, 52, 58, 60], "implement": [0, 28, 29, 34, 41, 44, 50, 52, 60], "authenticatorsess": 0, "an": [0, 1, 2, 3, 9, 13, 15, 16, 22, 23, 25, 27, 28, 29, 35, 36, 39, 40, 41, 44, 46, 49, 50, 56, 60], "instanc": [0, 2, 23, 28, 29, 40, 48, 53], "creat": [0, 2, 3, 19, 23, 29, 30, 34, 35, 37, 40, 41, 43, 46, 47, 49, 50, 51, 57, 58, 60], "per": [0, 2, 29, 42], "so": [0, 2, 3, 25, 26, 28, 29, 32, 35, 40, 42, 50], "also": [0, 2, 16, 19, 25, 26, 27, 28, 29, 32, 43, 44, 49, 50, 52, 53], "necessari": [0, 40], "authenticatorprovid": 0, "final": [0, 32, 60], "make": [0, 10, 21, 27, 29, 32, 35, 40, 44, 48, 50], "authenticator_provid": 0, "byte": 0, "bufmut": [0, 32], "bytesmut": 0, "async_trait": 0, "autherror": 0, "struct": [0, 7, 8, 19, 32, 37, 44, 60], "customauthent": 0, "impl": [0, 32], "handl": [0, 2, 19, 22, 23, 29, 39, 41, 49, 50, 51, 54, 55], "challeng": 0, "initi": [0, 29, 50, 52], "inform": [0, 2, 8, 16, 19, 29, 32, 34, 36, 41, 44, 50, 53, 60, 61], "contain": [0, 2, 27, 29, 34, 35, 39, 57, 58, 59, 61], "token": [0, 29, 34, 37, 41], "paramet": [0, 19, 35, 60], "protocol": [0, 32], "specif": [0, 25, 28, 29, 35, 61], "It": [0, 1, 3, 9, 15, 16, 28, 29, 32, 35, 36, 39, 42, 43, 49, 50, 52, 55, 61], "mai": [0, 28, 32, 42, 50], "null": [0, 19], "empti": [0, 34, 36, 41, 44], "async": [0, 1, 2, 30, 36, 45, 46, 53], "fn": [0, 1, 2, 30, 32, 45, 46, 53], "evaluate_challeng": 0, "mut": [0, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 32, 34, 35, 36, 37, 41, 42, 44, 46, 49, 50, 51, 52, 57, 58, 59, 60], "self": [0, 2, 32], "_token": 0, "option": [0, 19, 23, 25, 27, 29, 32, 35, 39, 41, 44, 57], "u8": [0, 5, 8], "result": [0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 30, 32, 34, 36, 37, 38, 42, 44, 46, 52, 53, 59, 60], "vec": [0, 5, 6, 8, 10, 39, 41], "err": [0, 40], "expect": [0, 16, 32], "to_str": [0, 1, 2, 6, 14, 18, 19, 28, 30, 35, 42, 44, 46, 53], "success": [0, 29, 37, 52, 60], "phase": 0, "exchang": 0, "request": [0, 2, 22, 23, 25, 28, 29, 31, 32, 34, 36, 41, 42, 44, 50, 54, 59, 60], "ok": [0, 1, 2, 30, 40, 46, 50, 53], "customauthenticatorprovid": 0, "start_authentication_sess": 0, "_name": 0, "str": [0, 8, 10, 14, 21, 32, 44], "box": [0, 1, 2, 24, 30, 46, 49, 50, 51, 53], "dyn": [0, 1, 2, 30, 46, 53], "respons": [0, 28, 32, 38, 39, 42, 60], "cred": 0, "0cassandra": 0, "cred_length": 0, "20": 0, "put_i32": 0, "put_slic": 0, "as_byt": 0, "some": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 32, 35, 36, 37, 39, 40, 41, 42, 44, 46, 49, 50, 51, 52, 54, 55, 57, 58, 60, 61], "to_vec": 0, "authentication_exampl": 0, "error": [0, 1, 2, 15, 29, 30, 31, 39, 42, 46, 51, 52, 53, 60], "_session": 0, "arc": [0, 2, 24, 29, 49, 54, 55, 60], "By": [1, 2, 28, 32, 34, 37, 41, 44, 50, 52], "default": [1, 2, 19, 22, 24, 25, 28, 29, 30, 34, 35, 37, 40, 41, 42, 44, 52, 56, 57], "doe": [1, 32, 41, 42, 55, 60, 61], "us": [1, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 40, 41, 42, 44, 45, 46, 49, 50, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61], "ani": [1, 2, 9, 10, 15, 16, 19, 21, 23, 25, 31, 32, 35, 36, 37, 60, 61], "connect": [1, 27, 29, 30, 43, 59], "": [1, 2, 3, 9, 15, 16, 19, 25, 26, 28, 29, 32, 34, 35, 36, 37, 39, 41, 43, 44, 48, 52, 53, 60, 61], "possibl": [1, 28, 29, 32, 34, 36, 39, 42, 43, 52, 60, 61], "prefer": [1, 25, 36, 43], "algorithm": 1, "The": [1, 2, 3, 8, 19, 23, 28, 29, 30, 32, 35, 39, 40, 41, 42, 43, 48, 49, 50, 51, 53, 55, 60, 61], "try": [1, 2, 28, 29, 50, 60], "databas": [1, 2, 3, 8, 15, 16, 19, 27, 29, 32, 41, 44, 53, 61], "doesn": [1, 2, 3, 16, 37, 38, 60, 61], "t": [1, 2, 3, 6, 7, 8, 15, 16, 32, 36, 37, 38, 39, 40, 41, 43, 60, 61], "fall": [1, 28, 42], "back": [1, 42], "avail": [1, 9, 15, 16, 21, 25, 28, 30, 38, 55, 56, 61], "snappi": 1, "lz4": 1, "exampl": [1, 2, 3, 8, 19, 27, 29, 30, 32, 34, 37, 41, 43, 44, 46, 47, 53], "enabl": [1, 9, 10, 15, 16, 21, 26, 28, 29, 38, 56, 57, 58, 59, 60], "transport": [1, 22, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55, 58], "std": [1, 2, 3, 6, 8, 10, 12, 21, 22, 24, 28, 29, 30, 42, 46, 53, 54, 55, 60], "tokio": [1, 2, 30, 45, 46, 53], "main": [1, 2, 30, 45, 46, 53], "uri": [1, 2, 29, 30, 42, 46, 53], "env": [1, 2, 30, 42, 45, 46, 53], "var": [1, 2, 30, 42, 46, 53], "scylla_uri": [1, 2, 30, 42, 46, 53], "unwrap_or_els": [1, 2, 30, 42, 46, 53], "_": [1, 2, 30, 32, 36, 42, 46, 53], "i": [2, 3, 5, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 23, 25, 27, 28, 29, 30, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 48, 49, 50, 52, 53, 54, 56, 58, 59, 60, 61], "distribut": [2, 28], "which": [2, 3, 10, 17, 21, 23, 25, 28, 29, 30, 32, 34, 36, 37, 39, 40, 41, 44, 46, 57, 60, 61], "mean": [2, 28, 29, 32, 36, 44, 48], "oper": [2, 28, 31, 34, 42, 44, 50, 61], "multipl": [2, 38, 52, 56, 58], "node": [2, 29, 34, 36, 37, 40, 41, 42, 46, 50, 56, 60, 61], "run": [2, 23, 27, 30, 34, 37, 38, 43, 45, 47, 49, 50, 51, 60], "independ": 2, "when": [2, 19, 27, 28, 29, 32, 35, 37, 38, 39, 41, 42, 43, 44, 49, 54, 60, 61], "you": [2, 3, 19, 25, 26, 28, 29, 30, 32, 34, 37, 38, 40, 41, 44, 49, 50, 61], "can": [2, 5, 7, 9, 10, 15, 16, 19, 21, 23, 25, 26, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 48, 49, 50, 52, 53, 56, 60, 61], "few": [2, 27, 39, 44, 47], "known": 2, "time": [2, 8, 22, 24, 28, 32, 40, 41, 42, 52, 54, 55, 60], "durat": [2, 8, 22, 24, 28, 40, 42, 54, 55], "net": [2, 8, 12], "ipaddr": [2, 8, 12], "ipv4addr": [2, 12], "socketaddr": 2, "72": 2, "4321": 2, "localhost": 2, "8000": 2, "connection_timeout": 2, "from_sec": [2, 22, 24, 28, 40, 42], "3": [2, 5, 6, 8, 9, 10, 11, 15, 21, 24, 28, 32, 34, 42, 44, 45, 50, 54, 55], "cluster_metadata_refresh_interv": 2, "10": [2, 3], "known_node_addr": 2, "v4": [2, 12], "9000": 2, "after": [2, 19, 28, 32, 40, 48, 52, 55, 61], "successfulli": [2, 29], "fetch": [2, 27, 36, 41, 58, 61], "topologi": 2, "about": [2, 8, 27, 29, 32, 34, 41, 44, 48, 60, 61], "other": [2, 9, 15, 16, 19, 28, 29, 32, 35, 37, 43, 50, 60], "thi": [2, 19, 23, 26, 27, 28, 29, 30, 32, 34, 36, 37, 38, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 60, 61], "them": [2, 25, 27, 28, 32, 34, 37, 38, 39, 41, 44, 46, 60], "well": [2, 28], "alwai": [2, 25, 35, 37, 50], "onli": [2, 7, 9, 15, 16, 28, 29, 32, 34, 35, 37, 40, 41, 56], "singl": [2, 23, 32, 36, 38, 39, 41, 44, 52, 60], "object": [2, 23, 34], "apllic": 2, "becaus": [2, 3, 29, 36, 41], "veri": [2, 10, 21, 28, 32], "expens": 2, "maintain": 2, "its": [2, 9, 23, 28, 29, 32, 34, 52, 53, 56, 60], "own": [2, 19, 29], "pool": 2, "each": [2, 8, 28, 29, 32, 34, 36, 41, 44, 58, 59, 60], "capabl": [2, 53], "parallel": [2, 38, 60], "rout": [2, 28], "shard": [2, 29, 34, 37, 41], "actual": [2, 32, 42], "data": [2, 19, 27, 28, 29, 32, 34, 37, 41, 50], "unless": [2, 28, 32, 50], "load": [2, 23, 27, 28, 34, 37, 38, 41], "balanc": [2, 23, 27, 28, 34, 37, 38, 41], "polici": [2, 23, 27, 28, 54, 55, 60], "For": [2, 3, 19, 29, 32, 34, 35, 36, 37, 39, 40, 41, 43, 50], "those": [2, 25, 28, 32], "reason": [2, 32, 50], "we": [2, 5, 26, 32, 37, 40, 43, 44, 47, 48, 50, 60, 61], "recommend": [2, 28, 29, 32, 50], "one": [2, 19, 21, 25, 32, 34, 36, 37, 39, 42, 43, 49, 50, 53, 55, 60], "applic": [2, 28, 40, 42, 52], "short": 2, "live": [2, 50], "e": [2, 9, 28, 29, 32, 35, 40, 42], "g": [2, 28, 29, 32, 35, 40], "strongli": [2, 34], "discourag": [2, 34], "great": 2, "perform": [2, 28, 29, 32, 38, 40, 44, 58, 60, 61], "penalti": [2, 36], "costli": 2, "process": [2, 42], "requir": [2, 9, 16, 19, 32, 35, 36, 41, 44, 48, 50], "estabilish": 2, "lot": [2, 40], "tcp": 2, "mani": [2, 34, 38, 60], "thread": 2, "task": 2, "wast": 2, "resourc": 2, "mention": [2, 32], "befor": [2, 9, 28, 32, 34, 37, 38, 40, 56], "itself": [2, 32, 35, 39, 52], "queri": [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 40, 47, 48, 49, 50, 51, 55, 56, 59], "would": [2, 32, 52, 60, 61], "hold": 2, "unnecessarili": 2, "If": [2, 9, 15, 16, 28, 32, 36, 37, 40, 41, 42, 43, 44, 50, 58, 59, 61], "need": [2, 3, 29, 36, 37, 38, 39, 40, 41, 43, 48, 61], "share": [2, 23, 54], "differ": [2, 9, 15, 16, 19, 23, 27, 35, 43, 44], "etc": [2, 27, 60, 61], "all": [2, 16, 22, 23, 26, 27, 28, 30, 32, 34, 37, 38, 40, 41, 52, 58, 59, 60, 61], "take": [2, 32, 34, 36, 37, 41], "hinder": 2, "function": [2, 3, 38, 40], "wai": [2, 23, 26, 36, 37, 39, 41, 48, 61], "refresh": 2, "period": [2, 53], "schema": [2, 27, 32], "everi": [2, 28, 40], "60": 2, "second": [2, 15, 16, 32, 34, 42, 43, 56], "howev": [2, 9, 15, 16, 32, 40, 42, 60], "set": [2, 8, 23, 27, 28, 29, 32, 34, 35, 37, 41, 42, 43, 47, 49, 50, 51, 61], "non": [2, 28, 34, 35, 36, 52, 55, 56, 60], "neg": [2, 15], "valu": [2, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 28, 35, 36, 37, 40, 43, 46, 49, 50, 51, 57, 58, 61], "do": [2, 27, 29, 32, 34, 40, 50, 60], "have": [2, 3, 19, 25, 26, 29, 30, 32, 34, 35, 36, 37, 39, 40, 42, 44, 50], "unexpect": 2, "amount": [2, 37, 41, 60], "traffic": [2, 28], "extra": [2, 9, 15, 16], "caus": [2, 29, 37, 41], "chang": [2, 19, 23, 26, 33, 34, 35, 37, 40, 41, 44, 52, 60], "frequent": 2, "elast": 2, "dynam": 2, "deploy": 2, "model": 2, "secur": 2, "bundl": 2, "follow": [2, 8, 9, 15, 16, 17, 23, 24, 25, 26, 28, 32, 50, 53, 61], "path": [2, 3], "cloudsessionbuild": 2, "config_data": 2, "yaml": 2, "unwrap": [2, 9, 15, 16, 31, 39], "note": [2, 19, 28, 32, 34, 37, 42, 50], "file": [2, 3], "provid": [2, 29, 32, 37, 39, 42, 44, 60, 61], "here": [2, 28, 39, 41, 46, 60], "configur": [2, 23, 27, 28, 30, 32, 56], "datacent": [2, 35, 50], "datacenter1": 2, "certificateauthoritydata": 2, "certificate_data": 2, "server": [2, 42], "9142": [2, 3], "nodedomain": 2, "cql": [2, 8, 19, 32, 35, 43, 48], "id": [2, 57, 58, 59, 61], "com": 2, "insecureskiptlsverifi": 2, "fals": [2, 28, 40, 43], "authinfo": 2, "clientcertificatedata": 2, "clientkeydata": 2, "key_data": 2, "scylladb": [2, 42, 48], "context": 2, "datacenternam": 2, "authinfonam": 2, "currentcontext": 2, "openssl": 3, "crate": [3, 10, 30, 32, 60], "wa": [3, 19, 29, 37, 39, 50, 57, 61], "chosen": 3, "rustl": 3, "certif": 3, "ip": [3, 12], "address": [3, 12, 28], "see": [3, 8, 9, 15, 16, 19, 26, 29, 32, 34, 35, 37, 39, 41, 43, 44, 50, 60], "issu": [3, 32, 36, 44], "common": [3, 23, 29], "case": [3, 9, 15, 16, 25, 28, 29, 32, 36, 37, 40, 41, 50, 52, 60], "pure": 3, "rust": [3, 8, 13, 18, 19, 28, 32, 35, 39, 41, 44, 47], "librari": 3, "instal": [3, 30, 47, 48], "proper": 3, "packag": 3, "add": [3, 34, 45], "cargo": [3, 30, 45], "toml": [3, 45], "version": [3, 27, 32, 33, 40, 45], "4": [3, 5, 6, 8, 16, 21, 32, 34, 45, 57, 58], "ssl": 3, "32": [3, 10], "Then": 3, "debian": 3, "ubuntu": 3, "apt": 3, "libssl": 3, "dev": 3, "pkg": 3, "config": 3, "fedora": 3, "dnf": 3, "devel": 3, "arch": 3, "pacman": 3, "sslcontext": 3, "pass": [3, 29, 34, 37, 41, 44, 60], "ca": 3, "crt": 3, "sslcontextbuild": 3, "sslmethod": 3, "sslverifymod": 3, "pathbuf": 3, "context_build": 3, "set_ca_fil": 3, "set_verifi": 3, "peer": 3, "port": 3, "now": [3, 19, 26, 32, 43, 45, 46, 58, 59], "ssl_context": 3, "full": [3, 9, 16, 30, 45], "more": [3, 8, 9, 15, 16, 19, 32, 34, 35, 36, 37, 39, 40, 41, 42, 44, 50, 52, 60, 61], "detail": [3, 29], "repres": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 32, 39, 41, 60], "intotypedrow": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 36, 39, 41, 46], "insert": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 34, 35, 37, 39, 41, 43, 44, 46, 49, 50, 51, 57, 58], "tabl": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 32, 35, 36, 37, 40, 41, 42, 43, 46, 53, 61], "refer": [5, 28, 29, 32, 44], "move": 5, "whole": [5, 34, 36, 56], "to_insert": [5, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 35, 37, 41, 46, 49, 50, 51], "2": [5, 6, 9, 11, 15, 32, 34, 36, 41, 44, 48, 50], "5": [5, 6, 32, 34], "INTO": [5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 34, 35, 37, 39, 41, 43, 44, 46, 49, 50, 51, 57, 58], "keyspac": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 30, 38, 40, 41, 42, 46, 53], "read": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 38, 41, 46, 50, 60], "from": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 29, 30, 36, 37, 39, 41, 43, 44, 46, 52, 57, 58, 59, 60, 61], "select": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 29, 32, 36, 39, 41, 43, 46, 52, 57, 58, 59, 60], "iter": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 29, 31, 36, 39, 41, 46, 53, 56, 58], "rows_typ": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 39, 41, 46], "while": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 32, 36, 41, 46, 58], "blob_valu": 5, "next": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 36, 41, 46, 50, 58, 60], "transpos": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 41, 46], "println": [5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 31, 36, 40, 41, 45, 46, 53, 57, 58, 59, 60], "int": [6, 8, 18, 19, 32, 37, 39, 44, 46], "my_list": 6, "i32": [6, 8, 13, 18, 19, 32, 35, 36, 37, 39, 41, 44, 46, 49, 50, 51], "list_valu": 6, "hashset": 6, "btreeset": 6, "my_set": 6, "collect": [6, 8], "into_it": 6, "hashmap": [6, 8, 44], "k": [6, 8, 19, 22, 24, 25, 26, 30, 34, 35, 36, 37, 39, 41, 44, 46, 49, 50, 51, 52, 57, 58, 59, 60], "v": [6, 8], "btreemap": 6, "text": [6, 8, 19, 34, 37, 39, 41, 44], "my_map": 6, "string": [6, 8, 14, 18, 19, 32, 35, 37, 39, 41, 44], "abcd": 6, "16": [6, 18, 34, 36, 37, 44], "map_valu": 6, "pub": [7, 32], "i64": [7, 8, 13, 15, 16], "updat": [7, 27, 29, 34, 40], "frame": [7, 9, 10, 11, 15, 16, 17, 39, 44], "c": [7, 36, 37, 41, 44, 48], "counter_valu": 7, "counter_int_valu": 7, "map": [8, 26, 44], "match": [8, 9, 15, 16, 19, 32, 39, 41, 44], "achiev": [8, 43, 50], "seamless": 8, "send": [8, 29, 32, 34, 36, 41, 43, 44, 60, 61], "receiv": [8, 19, 30, 32, 36, 37, 39, 41, 48, 58], "chapter": [8, 29, 47, 61], "how": [8, 27, 36, 53, 61], "equival": [8, 32], "boolean": 8, "bool": 8, "tinyint": 8, "i8": [8, 13], "smallint": 8, "i16": [8, 13, 32], "bigint": [8, 45], "float": 8, "f32": [8, 13], "doubl": 8, "f64": [8, 13], "ascii": 8, "varchar": 8, "counter": 8, "blob": 8, "inet": 8, "uuid": [8, 17, 45, 57, 58, 59], "timeuuid": 8, "cqltimeuuid": [8, 17], "date": [8, 16], "cqldate": 8, "chrono": 8, "naived": [8, 16], "cqltime": 8, "naivetim": [8, 16], "timestamp": [8, 60], "cqltimestamp": 8, "datetim": 8, "utc": [8, 16, 60], "offsetdatetim": 8, "cqldurat": [8, 11], "decim": 8, "cqldecim": 8, "bigdecim": [8, 45], "varint": 8, "cqlvarint": 8, "num_bigint": 8, "v0": [8, 21], "list": [8, 29, 34, 41, 44, 58, 59, 60], "tupl": [8, 34, 39, 41, 44], "udt": [8, 19, 32], "custom": [8, 17, 19, 29, 37, 41, 42, 44, 52], "macro": [8, 19, 39, 44], "depend": [9, 15, 16, 36, 45], "featur": [9, 10, 15, 16, 21, 45, 61], "flag": [9, 10, 15, 16, 21, 28, 61], "three": [9, 15, 16, 25, 28, 32, 44, 50, 52], "type": [9, 10, 15, 16, 21, 27, 32, 35, 38, 41, 53], "interact": [9, 10, 15, 16, 21], "intern": [9, 15, 16, 29], "number": [9, 10, 15, 16, 21, 27, 31, 32, 34, 39, 50], "dai": [9, 11], "sinc": [9, 15, 16], "5877641": 9, "06": 9, "23": [9, 15], "31": 9, "unix": [9, 16], "epoch": [9, 16], "without": [9, 10, 15, 16, 19, 21, 32, 39, 40, 43, 52, 60], "u32": 9, "wrapper": [9, 10, 15, 16, 17, 21, 32], "represent": [9, 15, 16, 32, 60], "most": [9, 15, 16, 29, 55], "ar": [9, 14, 15, 16, 19, 23, 25, 26, 28, 29, 32, 34, 36, 37, 38, 39, 41, 43, 44, 50, 52, 56, 58, 59, 61], "practic": [9, 15, 16, 32], "section": [9, 15, 16, 32, 37], "1970": [9, 16], "01": [9, 15, 16], "08": [9, 60], "7": [9, 36], "raw": [9, 32, 43], "row": [9, 10, 15, 16, 17, 36, 41, 43, 46, 58], "into_typ": [9, 10, 15, 16, 17, 36], "date_valu": 9, "rang": [9, 16, 28], "262145": 9, "262143": 9, "12": [9, 45], "2021": 9, "03": [9, 15, 21], "24": 9, "from_ymd_opt": [9, 16], "altern": [9, 16], "document": [9, 19, 34, 35, 37, 41, 44, 50], "get": [9, 39, 60, 61], "info": [9, 16, 30, 57, 58, 59], "month": [9, 11, 16], "from_calendar_d": [9, 16], "march": 9, "simpl": [10, 21, 27, 32, 34, 36, 37, 38, 47, 49, 50, 51, 56, 58], "sign": [10, 21], "binari": [10, 21], "big": [10, 21, 36], "endian": [10, 21], "order": [10, 17, 19, 21, 32, 36, 41, 44, 53, 60], "bit": [10, 39], "scale": 10, "fromstr": [10, 21], "123": [10, 13, 16], "456": [10, 15], "from_signed_be_bytes_and_expon": 10, "0x01": 10, "0xe2": 10, "0x40": 10, "decimal_valu": 10, "should": [10, 21, 30, 32, 41, 44, 45, 48], "04": [10, 16, 21], "from_str": [10, 17, 21], "12345": [10, 13, 21, 35, 37, 41, 43, 46, 49, 50, 51], "nanosecond": [11, 15], "duration_valu": 11, "inet_valu": 12, "true": [13, 28, 43, 52, 57, 58, 59], "bool_valu": 13, "tinyint_valu": 13, "smallint_valu": 13, "int_valu": [13, 18, 39], "bigint_valu": 13, "float_valu": 13, "double_valu": 13, "to_insert_str": 14, "abcdef": 14, "text_valu": [14, 39], "midnight": 15, "exce": 15, "86399999999999": 15, "59": 15, "999999999": 15, "64": [15, 16], "1_000_000_000": 15, "time_valu": 15, "although": [15, 27], "leap": 15, "thei": [15, 19, 21, 28, 29, 31, 32, 34, 37, 41, 44], "attempt": [15, 60, 61], "convert": [15, 16, 29, 39, 60], "write": [15, 16, 19, 28, 43, 50], "return": [15, 16, 28, 29, 32, 36, 37, 39, 40, 41, 42, 50, 51, 52, 57], "02": 15, "789": 15, "012": 15, "from_hms_nano_opt": 15, "456_789_012": 15, "from_hms_nano": 15, "describ": [16, 26, 32], "millisecond": [16, 40], "accept": 16, "00": 16, "1000": 16, "timestamp_valu": 16, "timezon": 16, "explicitli": 16, "store": [16, 28], "precis": 16, "finer": 16, "than": [16, 28, 37, 39, 40, 42, 43, 44, 50], "1m": 16, "lost": 16, "naivedatetim": 16, "from_hms_milli_opt": 16, "and_utc": 16, "As": [16, 26, 28, 32, 41, 42], "correct": [16, 28, 32], "eras": 16, "On": [16, 29, 36, 50], "primitivedatetim": 16, "januari": 16, "from_hms_milli": 16, "assume_utc": 16, "logic": [17, 42], "cassandra": [17, 27, 29, 42, 61], "semant": 17, "8e14e760": [17, 20], "7fa8": [17, 20], "11eb": [17, 20], "bc66": [17, 20], "000000000001": [17, 20], "timeuuid_valu": 17, "max": [18, 44], "element": [18, 29, 44], "abc": 18, "tuple_valu": 18, "string_valu": 18, "allow": [19, 23, 28, 29, 32, 34, 36, 38, 43, 60, 61], "name": [19, 32, 39, 43, 44], "field": [19, 28, 32, 39, 44], "offici": 19, "correspond": [19, 50], "sai": [19, 37, 61], "my_typ": 19, "int_val": 19, "text_val": 19, "deriv": [19, 32, 39, 44], "serializecql": 19, "abl": [19, 28, 29, 52, 60], "same": [19, 28, 29, 32, 35, 36, 37, 39, 43, 44, 49, 50, 60, 61], "renam": 19, "attribut": [19, 32, 44], "fromusertyp": [19, 32], "mismatch": 19, "between": [19, 23, 34], "temporari": 19, "situat": [19, 52], "futur": [19, 29, 32, 36, 40, 45, 58], "replac": [19, 32], "earlier": 19, "must": [19, 28, 32, 34, 37, 39, 44], "wrap": [19, 32, 43], "gracefulli": 19, "debug": [19, 51], "mytyp": 19, "import": [19, 35], "deseri": [19, 32], "de": 19, "serial": [19, 23, 24, 33, 35, 36, 41], "anoth": [19, 22, 23, 26, 32, 50, 55, 56, 60], "look": [19, 32], "behaviour": [19, 40, 49, 50], "sent": [19, 29, 32, 34, 37, 41, 44, 60, 61], "just": [19, 30, 32, 34, 35, 36, 37, 43, 44, 52, 60], "like": [19, 34, 35, 36, 37, 48, 60, 61], "cql_to_rust": [19, 39], "fromcqlval": 19, "17": [19, 44, 48], "my_type_valu": 19, "parse_str": 20, "uuid_valu": 20, "num": [21, 45], "accordingli": 21, "varint_valu": 21, "executionprofil": [22, 23, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55], "attach": 22, "statement": [22, 23, 24, 25, 26, 28, 32, 35, 37, 38, 41, 42, 57], "consist": [22, 23, 24, 25, 26, 28, 34, 35, 37, 41, 52, 60], "builder": [22, 24, 25, 26, 28, 29, 42, 49, 50, 51, 54, 55], "localon": 22, "request_timeout": [22, 24, 42], "none": [22, 28, 29, 42, 44], "timeout": [22, 23, 25, 40, 50], "into_handl": [22, 24, 25, 26, 29, 42, 49, 50, 51, 54, 55], "default_execution_profile_handl": [22, 25, 26, 29, 42, 49, 50, 51, 54, 55], "30": [22, 24, 28, 42], "query1": [22, 26], "set_execution_profile_handl": [22, 24, 25, 26, 42, 49, 50, 51], "clone": [22, 25, 26, 36, 60], "query2": [22, 26], "pk": [22, 26, 32], "where": [22, 26, 32, 36, 40, 41, 50, 52, 56], "base": [22, 28, 29, 30, 32, 49, 50, 52], "base_profil": 22, "to_build": 22, "group": [23, 27, 28], "variou": [23, 27, 31, 34], "togeth": [23, 27], "workload": [23, 26, 28], "conveni": [23, 26, 35], "encapsul": 23, "retri": [23, 27, 31, 40, 60, 61], "specul": [23, 29, 61], "There": [23, 28, 56, 61], "two": [23, 25, 26, 29, 32, 34, 35, 39, 43, 48, 50, 61], "class": [23, 30, 46], "relat": 23, "executionprofilehandl": [23, 26], "former": 23, "simpli": [23, 29, 41, 44, 60], "immut": 23, "latter": 23, "particular": [23, 28, 29], "moment": [23, 31], "point": 23, "dure": [23, 31, 32, 56], "lifetim": 23, "assign": [23, 25, 26, 28], "At": 23, "remap": 23, "switch": [23, 26, 27], "characterist": 23, "speculative_execut": [24, 54, 55], "simplespeculativeexecutionpolici": [24, 55], "serialconsist": [24, 35], "load_balanc": [24, 28, 29], "defaultpolici": [24, 29], "retry_polici": [24, 49, 50, 51], "fallthroughretrypolici": [24, 51], "sync": [24, 29, 32, 54, 55, 60], "serial_consist": 24, "load_balancing_polici": [24, 29], "speculative_execution_polici": [24, 54, 55], "max_retry_count": [24, 54, 55], "retry_interv": [24, 55], "from_milli": [24, 55], "100": [24, 55], "profil": [25, 27, 29, 49], "either": [25, 60], "overridden": 25, "upon": [25, 40], "creation": [25, 56], "moreov": 25, "ha": [25, 28, 32, 41, 43, 50, 52, 54, 56, 60, 61], "higher": 25, "directli": [25, 32], "In": [25, 28, 29, 32, 36, 37, 41, 43, 45, 47, 50, 53, 60], "over": [25, 32, 36], "recap": 25, "session_profil": 25, "One": [25, 26, 34, 35, 37, 41, 50], "query_profil": 25, "appli": [25, 28, 32, 52], "therefor": [25, 40, 43, 50], "set_consist": [25, 34, 35, 37, 41], "affect": [26, 28, 32, 36, 41], "been": [26, 40, 50], "quick": [26, 27], "session1": 26, "handle1": 26, "profile1": 26, "statement1": 26, "statement2": 26, "handle2": 26, "profile2": 26, "becom": [26, 28, 35], "yield": [26, 42], "power": 26, "modifi": [26, 34], "your": [26, 29, 36, 44], "below": [26, 32, 42, 50, 53], "abov": [26, 28, 54], "code": [26, 27, 29], "map_to_another_profil": 26, "book": 27, "written": [27, 30, 32], "optim": [27, 29, 56], "compat": [27, 32], "apach": 27, "lesson": 27, "univers": 27, "api": [27, 34, 35, 37, 41], "start": [27, 30, 36, 48, 55, 56, 60], "up": [27, 43, 47, 50], "project": [27, 47], "migrat": [27, 40], "guid": 27, "older": 27, "cluster": [27, 28, 29, 36, 37, 41, 50, 53], "prepar": [27, 28, 29, 36, 38, 41, 49, 50, 51, 52, 58, 61], "batch": [27, 32, 35, 38, 61], "page": [27, 31, 32, 37, 38, 41], "execut": [27, 28, 29, 30, 32, 34, 36, 39, 40, 41, 42, 49, 50, 51, 57], "onc": [27, 32, 34, 38, 53, 60], "column": [27, 32, 39, 44, 53], "what": [27, 43, 60, 61], "fail": [27, 29, 32, 39, 50, 52, 60], "idempot": 27, "metric": [27, 54], "statist": [27, 29], "latenc": [27, 29, 31, 43, 56], "log": [27, 50], "view": [27, 30, 53], "integr": 27, "produc": [27, 32], "trace": [27, 30, 45, 60], "inspect": 27, "local": [28, 35, 42], "mode": 28, "defaultpolicybuild": 28, "rack": 28, "is_token_awar": 28, "permit_dc_failov": 28, "latency_awar": 28, "desir": 28, "default_polici": 28, "prefer_datacenter_and_rack": 28, "dc1": 28, "rack1": 28, "token_awar": 28, "priorit": 28, "locat": 28, "my_dc": 28, "treat": [28, 44], "remot": 28, "zone": 28, "too": 28, "first": [28, 29, 32, 34, 36, 37, 39, 43, 55, 56, 60], "replica": [28, 29, 50], "similarli": 28, "disabl": [28, 29, 32, 40], "includ": [28, 29, 32, 34, 47, 60], "exclud": 28, "even": [28, 34, 50], "aliv": [28, 50], "serv": 28, "event": [28, 57, 58, 59, 60, 61], "outag": 28, "network": 28, "failur": [28, 29, 40, 52], "unavail": [28, 50], "client": [28, 48], "longer": 28, "access": [28, 31, 43, 54, 60], "permit": 28, "due": [28, 34], "constraint": 28, "mechan": [28, 40], "partit": [28, 37], "across": 28, "want": [28, 32, 40, 44], "being": [28, 29, 32, 34, 39, 50], "help": [28, 29, 39, 49], "minim": 28, "improv": 28, "ensur": [28, 32, 39], "much": [28, 32, 37], "within": [28, 35], "assum": 28, "significantli": 28, "scalabl": 28, "built": [28, 32], "reduc": 28, "overhead": [28, 32], "throughput": 28, "pleas": [28, 35, 48], "penalis": 28, "whose": 28, "measur": 28, "recent": 28, "averag": [28, 31], "classifi": 28, "behind": 28, "update_r": 28, "global": [28, 30, 42], "minimum": 28, "comput": [28, 29, 37], "wors": [28, 43], "exclusion_threshold": 28, "retry_period": 28, "involv": 28, "put": [28, 34, 45], "end": [28, 43, 60], "often": 28, "truli": 28, "benefici": 28, "faster": 28, "lag": 28, "worsen": [28, 37, 41], "warn": [28, 30, 34, 36, 37, 41], "NOT": [28, 30, 35, 40, 46], "prior": 28, "benchmark": 28, "prove": 28, "impact": 28, "caution": 28, "latencyawarenessbuild": 28, "latency_awareness_build": 28, "minimum_measur": 28, "200": [28, 40], "further": 28, "customis": 28, "cours": 28, "prefer_datacent": 28, "down": [28, 29, 40], "And": 28, "ones": [28, 32, 61], "prioriti": 28, "shuffl": 28, "randomli": 28, "rotat": 28, "round": [28, 32, 36, 41], "robin": 28, "random": [28, 34, 41], "index": 28, "optimis": 28, "lwt": 28, "ring": 28, "prevent": 28, "content": 28, "paxo": 28, "conflict": 28, "determin": [29, 50], "contact": 29, "gener": [29, 30, 32, 44], "state": [29, 43], "influenc": 29, "open": 29, "blacklist": 29, "host_filt": 29, "hostfilt": 29, "wide": 29, "target": 29, "pair": 29, "construct": 29, "essenti": [29, 32], "best": [29, 32, 34, 36, 43, 50], "might": [29, 32, 36, 37, 39, 40, 41, 44, 48, 49, 52, 60], "better": [29, 37, 38, 44, 50], "suit": 29, "our": [29, 32], "awar": [29, 34, 37, 41], "via": [29, 35], "sampl": [29, 60], "newli": [29, 32], "addit": [29, 32, 35, 36], "through": [29, 32], "level": [29, 35, 50], "basi": 29, "usual": 29, "unnecessari": 29, "entir": 29, "given": [29, 39, 42, 54], "rest": [29, 35], "call": [29, 32, 34, 53, 60], "layer": 29, "filter": [29, 45], "out": [29, 52, 60], "feedback": 29, "health": 29, "decis": [29, 60, 61], "hand": 29, "messag": [29, 30, 48], "overload": 29, "avoid": [29, 39, 43], "again": [29, 32, 40], "until": [29, 42, 60], "recov": 29, "subscrib": [30, 45], "print": [30, 41, 45, 46, 53, 60], "collector": [30, 60], "rust_log": 30, "tracing_subscrib": 30, "fmt": 30, "init": 30, "IF": [30, 35, 46], "exist": [30, 32, 35, 46], "WITH": [30, 46], "replic": [30, 46, 53], "networktopologystrategi": [30, 46], "replication_factor": [30, 46], "folder": 30, "get_metr": 31, "total": 31, "nonpag": 31, "get_queries_num": 31, "get_queries_iter_num": 31, "occur": [31, 53], "get_errors_num": 31, "get_errors_iter_num": 31, "get_latency_avg_m": 31, "99": [31, 54], "9": 31, "percentil": [31, 56], "get_latency_percentile_m": 31, "bind": [32, 34, 44], "marker": [32, 34, 44], "untyp": 32, "form": 32, "safer": 32, "robust": 32, "interfac": 32, "check": [32, 44, 60], "against": [32, 56], "couldn": 32, "kind": 32, "valuelist": [32, 34], "serializedresult": 32, "write_to_request": 32, "buf": 32, "serializevalueserror": 32, "naiv": 32, "hope": [32, 60], "took": 32, "care": [32, 60], "db": 32, "side": [32, 42], "valid": 32, "worst": 32, "reinterpret": 32, "unintend": 32, "manner": 32, "problem": [32, 43], "robustli": 32, "intousertyp": 32, "cumbersom": 32, "deprec": 32, "fix": 32, "previou": [32, 36], "core": 32, "AND": 32, "ck": 32, "associ": 32, "legacybatchvalu": 32, "previous": 32, "batchvalu": [32, 34], "sourc": 32, "were": [32, 61], "notabl": [32, 35], "cach": [32, 34], "come": 32, "did": 32, "correctli": 32, "ergonom": 32, "counterpart": 32, "fromrow": [32, 39], "limit": [32, 40, 42], "properli": [32, 37, 38, 39], "similar": 32, "rework": 32, "plan": 32, "releas": 32, "worth": 32, "keep": 32, "bring": 32, "cannot": [32, 50], "right": 32, "shown": 32, "snippet": 32, "exact": 32, "effect": 32, "complet": [32, 42, 61], "analog": 32, "flavor": [32, 44], "enforce_ord": [32, 44], "skip_name_check": 32, "person": 32, "surnam": 32, "ag": [32, 39], "learn": 32, "consider": 32, "concern": 32, "cachingsess": [32, 37], "alreadi": 32, "explain": 32, "done": [32, 34, 53, 60], "unprepar": [32, 34, 36], "skip": [32, 44, 61], "detect": 32, "noth": [32, 50], "along": [32, 60], "slowdown": 32, "incur": 32, "trip": [32, 36, 41], "uniqu": 32, "roundtrip": [32, 43], "unaccept": 32, "beforehand": 32, "reus": 32, "align": 32, "sensit": 32, "easi": [32, 38], "occurr": [32, 50], "ad": [32, 41, 44], "atribut": 32, "procedur": 32, "larg": [32, 37, 41], "enough": 32, "codebas": 32, "complic": 32, "everyth": [32, 46], "remov": 32, "rather": [32, 40], "util": [32, 61], "newtyp": 32, "valueadapt": 32, "valuelistadapt": 32, "legacybatchvaluesadapt": 32, "zero": 32, "cost": 32, "alloc": 32, "buffer": 32, "rewritten": 32, "shouldn": 32, "effici": 32, "legacybatchvaluesiter": 32, "write_next_to_request": 32, "natur": 32, "safe": 32, "convers": 32, "direct": [32, 42], "respect": 32, "impl_serialize_cql_via_valu": 32, "impl_serialize_row_via_value_list": 32, "11": [33, 60], "These": 34, "delet": [34, 44], "prepared_stat": [34, 36, 37, 49, 50, 51, 52, 57, 58, 59], "preparedstat": [34, 35, 36, 37, 49, 50, 51, 52, 57, 58, 59], "append_stat": [34, 57], "tab": [34, 35, 37, 39, 41, 43, 44, 49, 50, 51, 52, 57, 58, 59], "b": [34, 36, 37, 39, 41, 43, 44], "manual": [34, 35, 41, 49, 50, 51, 52, 57, 58, 61], "6": [34, 36, 45], "bound": [34, 37, 41, 44], "batch_valu": 34, "5_i32": 34, "sequenti": [34, 60], "consid": 34, "instead": [34, 36, 37, 41, 43], "individu": 34, "simple_unprepared1": 34, "simple_unprepared2": 34, "prepared_batch": 34, "prepare_batch": 34, "1_i32": [34, 44], "2_i32": [34, 41, 44], "3_i32": 34, "4_i32": 34, "length": 34, "equal": 34, "trait": [34, 44, 52], "slice": [34, 44], "unit": [34, 44], "third": [34, 60], "express": 35, "serial_consistency_level": 35, "separ": [35, 61], "simplequeri": 35, "lai": 35, "condit": 35, "rememb": 35, "localseri": 35, "variant": [35, 36], "commonli": 35, "cross": 35, "overrid": 35, "ONE": [35, 41], "my_queri": [35, 41, 49, 50, 51, 52], "set_serial_consist": 35, "remain": 35, "ident": 35, "sometim": [36, 40, 50], "fit": [36, 38], "query_it": [36, 61], "execute_it": [36, 61], "fulli": [36, 38], "amort": 36, "stream": [36, 60], "streamext": [36, 58], "rows_stream": 36, "next_row_r": 36, "set_page_s": 36, "extract": 36, "That": 36, "left": 36, "off": [36, 42], "paged_queri": 36, "with_page_s": 36, "res1": 36, "res2": 36, "query_pag": 36, "paging_st": 36, "paged_prepar": 36, "execute_pag": 36, "later": 37, "work": [37, 41], "kei": [37, 46, 53], "don": [37, 39, 41, 43], "unpag": [37, 41], "heavi": [37, 41], "size": [37, 41], "least": [37, 50], "succe": [37, 50, 60], "inherit": 37, "especi": 37, "good": 37, "otherwis": [37, 40, 50], "hash": 37, "wrong": 37, "prepare_t": 37, "primari": [37, 46, 53], "wrong_prepar": 37, "54321": [37, 43], "matter": [37, 41, 60], "good_prepar": 37, "poor": 38, "primit": 38, "fast": 38, "addition": [38, 41], "special": 38, "asynchron": 38, "wish": [38, 40, 42], "queryresult": [39, 41, 57], "awkward": 39, "as_ref": [39, 44], "as_int": 39, "rowt": 39, "maybe_first_row_typ": 39, "first_row_typ": 39, "maybe_first_row": 39, "single_row_typ": 39, "first_row": 39, "result_not_row": 39, "bug": [39, 40], "first_int_v": 39, "no_row": 39, "str_or_nul": 39, "myrow": 39, "my_row": 39, "agre": 40, "automat": 40, "alter": 40, "wait": [40, 60], "never": [40, 41, 44, 51, 52], "slow": 40, "somebodi": 40, "sens": 40, "said": 40, "auto_await_schema_agr": 40, "await_schema_agr": 40, "ed": 40, "long": 40, "won": 40, "forev": 40, "sessionconfig": 40, "elaps": 40, "queryerror": [40, 42], "requesttimeout": [40, 42], "schema_vers": 40, "sleep": 40, "schema_agreement_interv": 40, "check_schema_agr": 40, "is_som": 40, "els": 40, "IN": 40, "anyth": [41, 61], "Into": 41, "constant": [41, 44, 55], "variabl": [41, 44], "fill": [41, 44], "easiest": [41, 48, 55], "integ": [41, 44], "text2": 41, "could": [41, 42, 43, 44], "lead": [41, 44], "sql": [41, 44], "inject": [41, 44], "pars": 41, "read_row": [41, 46], "place": 41, "With": 41, "immedi": 42, "continu": [42, 60], "still": [42, 43, 50, 60], "progress": 42, "interrupt": 42, "current": [42, 50, 54, 56], "turn": 42, "no_timeout_profile_handl": 42, "block": 42, "indefinit": 42, "hang": 42, "truncat": 42, "three_sec_timeout_profile_handl": 42, "last": 42, "arriv": 42, "omit": 43, "cqlsh": 43, "my_keyspac": 43, "easili": 43, "other_keyspac": 43, "other_t": 43, "use_keyspac": 43, "test1": 43, "test2": 43, "argument": 43, "whether": 43, "slightli": 43, "half": 43, "insensit": 43, "altogeth": 43, "happen": [43, 50, 61], "lowercas": 43, "uppercas": 43, "serializerow": 44, "sort": 44, "intstr": 44, "int_str": 44, "42_i32": 44, "hello": [44, 45], "to_own": 44, "intstringcustom": 44, "first_valu": 44, "second_valu": 44, "int_string_custom": 44, "trail": 44, "coma": 44, "syntax": 44, "val": 44, "cqlvalu": 44, "avalu": 44, "bvalu": 44, "null_i32": 44, "tombston": 44, "maybeunset": 44, "suboptim": 44, "enum": 44, "unset_i32": 44, "sure": [44, 50], "instruct": 44, "myproject": 45, "13": 45, "36": 45, "14": 45, "r": 45, "readi": [46, 48], "small": 46, "extab": 46, "topic": 47, "docker": 47, "imag": 48, "linux": 48, "sudo": 48, "rm": 48, "p": 48, "smp": 48, "download": 48, "minut": 48, "listen": 48, "172": 48, "stop": 48, "press": 48, "ctrl": 48, "found": 48, "dockerhub": 48, "high": [49, 52], "chanc": [49, 50, 52], "datastax": [49, 50], "java": [49, 50], "defaultretrypolici": [49, 50], "set_retry_polici": 49, "lower": [50, 52], "bewar": 50, "break": 50, "guarante": 50, "word": 50, "quorum": 50, "preced": 50, "understood": 50, "highli": 50, "But": 50, "top": 50, "respond": [50, 60], "greater": 50, "writetyp": 50, "unloggedbatch": 50, "acknowledg": 50, "furthermor": 50, "ignor": 50, "except": 50, "rule": 50, "eachquorum": 50, "reach": 50, "overal": 50, "assumpt": 50, "host": [50, 54], "coordin": 50, "know": 50, "thu": 50, "silent": 50, "persist": 50, "idea": 50, "thing": 50, "someth": 50, "risk": 50, "stale": 50, "downgrading_consistency_retry_polici": 50, "downgradingconsistencyretrypolici": 50, "falthroughretrypolici": 51, "straight": [51, 52], "decid": [52, 60], "fallthrough": 52, "downgrad": 52, "behav": 52, "retrypolici": 52, "retrysess": 52, "increas": 52, "danger": 52, "figur": 52, "set_is_idempot": 52, "present": 53, "demand": 53, "newest": 53, "refresh_metadata": 53, "metadata": 53, "snapshot": 53, "examin": 53, "obtain": [53, 61], "belong": 53, "materi": 53, "strategi": [53, 56], "definit": 53, "partition": 53, "show": 53, "cluster_data": 53, "get_cluster_data": 53, "get_keyspace_info": 53, "keyspace_nam": 53, "keyspace_info": 53, "ttabl": 53, "tview": 53, "tudt": 53, "user_defined_typ": 53, "trigger": 54, "percentilespeculativeexecutionpolici": 54, "execution_profil": [54, 55], "delai": 55, "count": 55, "techniqu": 56, "pre": 56, "emptiv": 56, "repli": 56, "tracing_id": [57, 58, 59, 61], "tracinginfo": [57, 58, 59, 61], "set_trac": [57, 58, 59], "re": 57, "system_trac": [57, 58, 59, 61], "tracing_info": [57, 58, 59], "get_tracing_info": [57, 58, 59, 61], "subsequ": 58, "rowiter": 58, "row_iter": 58, "_row": 58, "get_tracing_id": 58, "prepare_tracing_id": 59, "to_prepar": 59, "fiber": 60, "historycollector": 60, "history_listen": 60, "set_history_listen": 60, "save": 60, "_ignore_error": 60, "structured_histori": 60, "clone_structured_histori": 60, "didn": 60, "encount": 60, "difficulti": 60, "start_tim": 60, "2022": 60, "25": 60, "21": 60, "50": 60, "445075147": 60, "445151628": 60, "447444362": 60, "447447970": 60, "had": 60, "troubl": 60, "26": 60, "15": 60, "28": 60, "525367409": 60, "219": 60, "525409294": 60, "yet": 60, "537074167": 60, "217": 60, "537126083": 60, "548050242": 60, "218": 60, "548089083": 60, "590052778": 60, "590078119": 60, "understand": 60, "answer": 60, "consult": 60, "made": [60, 61], "tri": 60, "quicker": 60, "spawn": 60, "wasn": 60, "acquir": 60, "analyz": 60, "structur": 60, "monitor": 61, "signifi": 61, "went": 61, "go": 61, "insid": 61, "think": 61}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"authent": 0, "import": 0, "The": 0, "default": [0, 32, 49], "credenti": 0, "ar": 0, "sent": 0, "plain": 0, "text": [0, 14], "server": 0, "For": 0, "thi": 0, "reason": 0, "i": [0, 32, 40], "highli": 0, "recommend": 0, "us": [0, 2, 3, 39, 43, 48], "conjunct": 0, "client": 0, "node": [0, 28], "encrypt": 0, "ssl": 0, "trust": 0, "network": 0, "environ": 0, "custom": [0, 32, 39, 60], "compress": 1, "connect": [2, 46], "cluster": 2, "best": 2, "practic": 2, "session": [2, 37, 58, 59], "metadata": 2, "scylla": [2, 27, 48], "cloud": 2, "serverless": 2, "tl": 3, "enabl": 3, "featur": 3, "blob": 5, "list": [6, 32], "set": [6, 22, 25], "map": 6, "counter": 7, "data": [8, 39, 44], "type": [8, 19, 39, 44], "date": 9, "cqldate": 9, "chrono": [9, 15, 16], "naived": 9, "time": [9, 15, 16], "decim": 10, "valu": [10, 21, 32, 34, 39, 41, 44], "cqldecim": 10, "bigdecim": 10, "durat": 11, "inet": 12, "bool": 13, "tinyint": 13, "smallint": 13, "int": 13, "bigint": [13, 21], "float": 13, "doubl": 13, "ascii": 14, "varchar": 14, "cqltime": 15, "naivetim": 15, "timestamp": 16, "cqltimestamp": 16, "datetim": 16, "offsetdatetim": 16, "timeuuid": 17, "tupl": 18, "user": 19, "defin": 19, "uuid": 20, "varint": 21, "num_bigint": 21, "cqlvarint": 21, "exampl": [21, 22, 24, 25, 26, 31, 36, 49, 50, 51, 54, 55, 60], "creat": [22, 28, 45], "profil": [22, 23, 24, 26], "execut": [23, 25, 26, 37, 54, 55, 56, 60, 61], "all": 24, "option": [24, 34, 37], "support": 24, "prioriti": 25, "remap": 26, "handl": 26, "rust": 27, "driver": [27, 31, 60], "other": [27, 39, 44], "document": 27, "content": 27, "defaultpolici": 28, "semant": 28, "prefer": 28, "datacent": 28, "failov": 28, "token": 28, "awar": 28, "latenc": 28, "order": 28, "produc": 28, "plan": [28, 29], "load": 29, "balanc": 29, "introduct": 29, "polici": [29, 49, 50, 51, 52], "configur": [29, 36, 52], "loadbalancingpolici": 29, "trait": [29, 32, 60], "pick": 29, "fallback": 29, "on_query_success": 29, "on_query_failur": 29, "log": 30, "metric": 31, "collect": [31, 60], "adjust": 32, "code": [32, 60], "chang": 32, "serial": 32, "api": 32, "introduc": 32, "0": 32, "11": 32, "background": 32, "old": 32, "v": 32, "new": 32, "migrat": [32, 33], "scenario": 32, "differ": 32, "behavior": 32, "serializerow": 32, "serializecql": 32, "macro": 32, "prepar": [32, 34, 37, 57, 59], "mandatori": 32, "non": 32, "empti": 32, "from": 32, "gradual": 32, "convert": 32, "an": 32, "object": 32, "implement": 32, "guid": 33, "batch": [34, 57], "statement": 34, "perform": [34, 36, 37, 41], "lightweight": 35, "transact": 35, "lwt": 35, "queri": [35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 52, 57, 58, 60, 61], "format": 35, "page": [36, 58], "size": 36, "pass": 36, "state": 36, "manual": [36, 40], "make": 38, "result": [39, 41], "basic": 39, "represent": 39, "pars": 39, "into_typ": 39, "conveni": 39, "method": 39, "null": [39, 44], "row": 39, "struct": 39, "schema": [40, 53], "agreement": 40, "autom": 40, "await": 40, "interv": 40, "check": 40, "now": 40, "simpl": [41, 46, 55, 57], "first": 41, "argument": 41, "second": 41, "timeout": 42, "keyspac": 43, "multipl": 43, "onc": 43, "case": 43, "sensit": 43, "unset": 44, "project": 45, "run": [46, 48], "quick": 47, "start": 47, "docker": 48, "more": 48, "inform": 48, "retri": [49, 50, 51, 52], "downgrad": 50, "consist": 50, "fallthrough": 51, "idempot": 52, "fetch": 53, "inspect": 53, "percentil": 54, "specul": [54, 55, 56, 60], "trace": [57, 58, 59, 61], "query_it": 58, "execute_it": 58, "histori": [60, 61], "output": 60, "how": 60, "No": 60, "structuredhistori": 60, "historylisten": 60}, "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": {"Inet": [[12, "inet"]], "Timestamp": [[16, "timestamp"]], "CqlTimestamp": [[16, "cqltimestamp"]], "chrono::DateTime": [[16, "chrono-datetime"]], "time::OffsetDateTime": [[16, "time-offsetdatetime"]], "Varint": [[21, "varint"]], "num_bigint::BigInt": [[21, "num-bigint-bigint"]], "value::CqlVarint": [[21, "value-cqlvarint"]], "Example": [[21, "example"], [22, "example"], [22, "id1"], [22, "id2"], [25, "example"], [26, "example"], [31, "example"], [24, "example"], [55, "example"], [54, "example"]], "Uuid": [[20, "uuid"]], "User defined types": [[19, "user-defined-types"]], "Time": [[15, "time"]], "CqlTime": [[15, "cqltime"]], "chrono::NaiveTime": [[15, "chrono-naivetime"]], "time::Time": [[15, "time-time"]], "Timeuuid": [[17, "timeuuid"]], "Execution profiles": [[23, "execution-profiles"]], "Ascii, Text, Varchar": [[14, "ascii-text-varchar"]], "Tuple": [[18, "tuple"]], "Creating a profile and setting it": [[22, "creating-a-profile-and-setting-it"]], "Bool, Tinyint, Smallint, Int, Bigint, Float, Double": [[13, "bool-tinyint-smallint-int-bigint-float-double"]], "Bool": [[13, "bool"]], "Tinyint": [[13, "tinyint"]], "Smallint": [[13, "smallint"]], "Int": [[13, "int"]], "Bigint": [[13, "bigint"]], "Float": [[13, "float"]], "Double": [[13, "double"]], "Authentication": [[0, "authentication"]], "Important: The default authentication credentials are sent in plain text to the server. For this reason, it is highly recommended that this be used in conjunction with client-to-node encryption (SSL), or in a trusted network environment.": [[0, "important-the-default-authentication-credentials-are-sent-in-plain-text-to-the-server-for-this-reason-it-is-highly-recommended-that-this-be-used-in-conjunction-with-client-to-node-encryption-ssl-or-in-a-trusted-network-environment"]], "Custom Authentication": [[0, "custom-authentication"]], "List, Set, Map": [[6, "list-set-map"]], "List": [[6, "list"]], "Set": [[6, "set"]], "Map": [[6, "map"]], "Blob": [[5, "blob"]], "Date": [[9, "date"]], "CqlDate": [[9, "cqldate"]], "chrono::NaiveDate": [[9, "chrono-naivedate"]], "time::Date": [[9, "time-date"]], "Decimal": [[10, "decimal"]], "value::CqlDecimal": [[10, "value-cqldecimal"]], "bigdecimal::BigDecimal": [[10, "bigdecimal-bigdecimal"]], "Connecting to the cluster": [[2, "connecting-to-the-cluster"]], "Best practices for using Session": [[2, "best-practices-for-using-session"]], "Metadata": [[2, "metadata"]], "Scylla Cloud Serverless": [[2, "scylla-cloud-serverless"]], "TLS": [[3, "tls"]], "Enabling feature": [[3, "enabling-feature"]], "Using TLS": [[3, "using-tls"]], "Compression": [[1, "compression"]], "Counter": [[7, "counter"]], "Data Types": [[8, "data-types"]], "Duration": [[11, "duration"]], "USE keyspace": [[43, "use-keyspace"]], "Multiple use queries at once": [[43, "multiple-use-queries-at-once"]], "Case sensitivity": [[43, "case-sensitivity"]], "Paged query": [[36, "paged-query"]], "Examples": [[36, "examples"], [49, "examples"], [50, "examples"], [51, "examples"]], "Configuring page size": [[36, "configuring-page-size"]], "Passing the paging state manually": [[36, "passing-the-paging-state-manually"]], "Performance": [[36, "performance"], [37, "performance"], [41, "performance"], [34, "performance"]], "Prepared query": [[37, "prepared-query"]], "Session::prepare": [[37, "session-prepare"]], "Session::execute": [[37, "session-execute"]], "Query options": [[37, "query-options"]], "Query values": [[44, "query-values"]], "NULL values": [[44, "null-values"], [39, "null-values"]], "Unset values": [[44, "unset-values"]], "Other data types": [[44, "other-data-types"], [39, "other-data-types"]], "Connecting and running a simple query": [[46, "connecting-and-running-a-simple-query"]], "Query timeouts": [[42, "query-timeouts"]], "Schema agreement": [[40, "schema-agreement"]], "Automated awaiting schema agreement": [[40, "automated-awaiting-schema-agreement"]], "Manually awaiting schema agreement": [[40, "manually-awaiting-schema-agreement"]], "Interval of checking for schema agreement": [[40, "interval-of-checking-for-schema-agreement"]], "Checking if schema is in agreement now": [[40, "checking-if-schema-is-in-agreement-now"]], "Query result": [[39, "query-result"], [41, "query-result"]], "Basic representation": [[39, "basic-representation"]], "Parsing using into_typed": [[39, "parsing-using-into-typed"]], "Parsing using convenience methods": [[39, "parsing-using-convenience-methods"]], "Parsing row as a custom struct": [[39, "parsing-row-as-a-custom-struct"]], "Making queries": [[38, "making-queries"]], "Creating a project": [[45, "creating-a-project"]], "Quick Start": [[47, "quick-start"]], "Simple query": [[41, "simple-query"]], "First argument - the query": [[41, "first-argument-the-query"]], "Second argument - the values": [[41, "second-argument-the-values"]], "Priorities of execution settings": [[25, "priorities-of-execution-settings"]], "Batch statement": [[34, "batch-statement"]], "Preparing a batch": [[34, "preparing-a-batch"]], "Batch options": [[34, "batch-options"]], "Batch values": [[34, "batch-values"]], "DefaultPolicy": [[28, "defaultpolicy"]], "Creating a DefaultPolicy": [[28, "creating-a-defaultpolicy"]], "Semantics of DefaultPolicy": [[28, "semantics-of-defaultpolicy"]], "Preferences": [[28, "preferences"]], "Datacenter Failover": [[28, "datacenter-failover"]], "Token awareness": [[28, "token-awareness"]], "Latency awareness": [[28, "latency-awareness"]], "Creating a latency aware DefaultPolicy": [[28, "creating-a-latency-aware-defaultpolicy"]], "Node order in produced plans": [[28, "node-order-in-produced-plans"]], "Adjusting code to changes in serialization API introduced in 0.11": [[32, "adjusting-code-to-changes-in-serialization-api-introduced-in-0-11"]], "Background": [[32, "background"]], "Old vs. new": [[32, "old-vs-new"]], "Migration scenarios": [[32, "migration-scenarios"]], "Different default behavior in SerializeRow/SerializeCql macros": [[32, "different-default-behavior-in-serializerow-serializecql-macros"]], "Preparing is mandatory with a non-empty list of values": [[32, "preparing-is-mandatory-with-a-non-empty-list-of-values"]], "Migrating from old to new traits gradually": [[32, "migrating-from-old-to-new-traits-gradually"]], "Converting an object implementing an old trait to a new trait": [[32, "converting-an-object-implementing-an-old-trait-to-a-new-trait"]], "Custom implementations of old traits": [[32, "custom-implementations-of-old-traits"]], "Lightweight transaction (LWT) query": [[35, "lightweight-transaction-lwt-query"]], "Format of the query": [[35, "format-of-the-query"]], "Remapping execution profile handles": [[26, "remapping-execution-profile-handles"]], "Load balancing": [[29, "load-balancing"]], "Introduction": [[29, "introduction"]], "Plan": [[29, "plan"]], "Policy": [[29, "policy"]], "Configuration": [[29, "configuration"]], "LoadBalancingPolicy trait": [[29, "loadbalancingpolicy-trait"]], "pick and fallback:": [[29, "pick-and-fallback"]], "on_query_success and on_query_failure:": [[29, "on-query-success-and-on-query-failure"]], "Logging": [[30, "logging"]], "Driver metrics": [[31, "driver-metrics"]], "Collected metrics:": [[31, "collected-metrics"]], "Scylla Rust Driver": [[27, "scylla-rust-driver"]], "Other documentation": [[27, "other-documentation"]], "Contents": [[27, "contents"]], "Migration guides": [[33, "migration-guides"]], "All options supported by a profile": [[24, "all-options-supported-by-a-profile"]], "Query tracing": [[61, "query-tracing"]], "Tracing": [[61, "tracing"]], "Query Execution History": [[61, "query-execution-history"], [60, "query-execution-history"]], "Example code": [[60, "example-code"]], "Output": [[60, "output"]], "How the driver executes queries": [[60, "how-the-driver-executes-queries"]], "No speculative execution": [[60, "no-speculative-execution"]], "Speculative execution": [[60, "speculative-execution"], [56, "speculative-execution"]], "StructuredHistory": [[60, "structuredhistory"]], "HistoryListener trait, custom history collecting": [[60, "historylistener-trait-custom-history-collecting"]], "Default retry policy": [[49, "default-retry-policy"]], "Retry policy configuration": [[52, "retry-policy-configuration"]], "Retry policies": [[52, "retry-policies"]], "Query idempotence": [[52, "query-idempotence"]], "Schema": [[53, "schema"]], "Fetching schema": [[53, "fetching-schema"]], "Inspecting schema": [[53, "inspecting-schema"]], "Tracing Session::prepare": [[59, "tracing-session-prepare"]], "Simple speculative execution": [[55, "simple-speculative-execution"]], "Running Scylla using Docker": [[48, "running-scylla-using-docker"]], "Running scylla": [[48, "running-scylla"]], "More information": [[48, "more-information"]], "Downgrading consistency retry policy": [[50, "downgrading-consistency-retry-policy"]], "Tracing a paged query": [[58, "tracing-a-paged-query"]], "Tracing Session::query_iter": [[58, "tracing-session-query-iter"]], "Tracing Session::execute_iter": [[58, "tracing-session-execute-iter"]], "Tracing a simple/prepared/batch query": [[57, "tracing-a-simple-prepared-batch-query"]], "Tracing a simple query": [[57, "tracing-a-simple-query"]], "Tracing a prepared query": [[57, "tracing-a-prepared-query"]], "Tracing a batch query": [[57, "tracing-a-batch-query"]], "Percentile speculative execution": [[54, "percentile-speculative-execution"]], "Fallthrough retry policy": [[51, "fallthrough-retry-policy"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/v0.13.0/sitemap.xml b/v0.13.0/sitemap.xml new file mode 100644 index 0000000000..3389fbb0c3 --- /dev/null +++ b/v0.13.0/sitemap.xml @@ -0,0 +1,2 @@ + +https://rust-driver.docs.scylladb.com/stable/connecting/authentication.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/compression.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/connecting.htmlhttps://rust-driver.docs.scylladb.com/stable/connecting/tls.htmlhttps://rust-driver.docs.scylladb.com/stable/contents.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/time.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/blob.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/timestamp.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/timeuuid.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/collections.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/tuple.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/counter.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/udt.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/uuid.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/data-types.htmlhttps://rust-driver.docs.scylladb.com/stable/load-balancing/load-balancing.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/varint.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/date.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/create-and-use.htmlhttps://rust-driver.docs.scylladb.com/stable/logging/logging.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/decimal.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/execution-profiles.htmlhttps://rust-driver.docs.scylladb.com/stable/metrics/metrics.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/duration.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/maximal-example.htmlhttps://rust-driver.docs.scylladb.com/stable/migration-guides/0.11-serialization.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/inet.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/priority.htmlhttps://rust-driver.docs.scylladb.com/stable/migration-guides/migration-guides.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/primitive.htmlhttps://rust-driver.docs.scylladb.com/stable/execution-profiles/remap.htmlhttps://rust-driver.docs.scylladb.com/stable/data-types/text.htmlhttps://rust-driver.docs.scylladb.com/stable/index.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/basic.htmlhttps://rust-driver.docs.scylladb.com/stable/load-balancing/default-policy.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/batch.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/paged.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/prepare.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/lwt.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/query-history.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/paged.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/usekeyspace.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/prepared.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/queries.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/values.htmlhttps://rust-driver.docs.scylladb.com/stable/tracing/tracing.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/result.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/create-project.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/schema-agreement.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/simple.htmlhttps://rust-driver.docs.scylladb.com/stable/queries/timeouts.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/example.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/quickstart.htmlhttps://rust-driver.docs.scylladb.com/stable/quickstart/scylla-docker.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/default.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/downgrading-consistency.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/fallthrough.htmlhttps://rust-driver.docs.scylladb.com/stable/retry-policy/retry-policy.htmlhttps://rust-driver.docs.scylladb.com/stable/schema/schema.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/percentile.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/simple.htmlhttps://rust-driver.docs.scylladb.com/stable/speculative-execution/speculative.htmlhttps://rust-driver.docs.scylladb.com/stable/genindex.htmlhttps://rust-driver.docs.scylladb.com/stable/404.htmlhttps://rust-driver.docs.scylladb.com/stable/search.html \ No newline at end of file diff --git a/v0.13.0/speculative-execution/percentile.html b/v0.13.0/speculative-execution/percentile.html new file mode 100644 index 0000000000..74e139d5a7 --- /dev/null +++ b/v0.13.0/speculative-execution/percentile.html @@ -0,0 +1,653 @@ + + + + + + + + + + + + + Percentile speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Percentile speculative execution

            +

            This policy has access to Metrics shared with session, and triggers +speculative execution when the request to the current host is above a +given percentile.

            +
            +

            Example

            +

            To use this policy in Session:

            +
            use std::{sync::Arc, time::Duration};
            +use scylla::{
            +    Session,
            +    SessionBuilder,
            +    speculative_execution::PercentileSpeculativeExecutionPolicy,
            +    transport::execution_profile::ExecutionProfile,
            +};
            +
            +let policy = PercentileSpeculativeExecutionPolicy  {
            +    max_retry_count: 3,
            +    percentile: 99.0,
            +};
            +
            +let handle = ExecutionProfile::builder()
            +    .speculative_execution_policy(Some(Arc::new(policy)))
            +    .build()
            +    .into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .default_execution_profile_handle(handle)
            +    .build()
            +    .await?;
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/speculative-execution/simple.html b/v0.13.0/speculative-execution/simple.html new file mode 100644 index 0000000000..140153373b --- /dev/null +++ b/v0.13.0/speculative-execution/simple.html @@ -0,0 +1,654 @@ + + + + + + + + + + + + + Simple speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Simple speculative execution

            +

            The easiest speculative execution policy available. It starts another +execution of a query after constant delay of retry_interval and does at most +max_retry_count speculative query executions (not counting the first, +non-speculative one).

            +
            +

            Example

            +

            To use this policy in Session:

            +
            use std::{sync::Arc, time::Duration};
            +use scylla::{
            +    Session,
            +    SessionBuilder,
            +    speculative_execution::SimpleSpeculativeExecutionPolicy,
            +    transport::execution_profile::ExecutionProfile,
            +};
            +
            +let policy = SimpleSpeculativeExecutionPolicy {
            +    max_retry_count: 3,
            +    retry_interval: Duration::from_millis(100),
            +};
            +
            +let handle = ExecutionProfile::builder()
            +    .speculative_execution_policy(Some(Arc::new(policy)))
            +    .build()
            +    .into_handle();
            +
            +let session: Session = SessionBuilder::new()
            +    .known_node("127.0.0.1:9042")
            +    .default_execution_profile_handle(handle)
            +    .build()
            +    .await?;
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/speculative-execution/speculative.html b/v0.13.0/speculative-execution/speculative.html new file mode 100644 index 0000000000..c43e491485 --- /dev/null +++ b/v0.13.0/speculative-execution/speculative.html @@ -0,0 +1,619 @@ + + + + + + + + + + + + + Speculative execution | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Speculative execution

            +

            Speculative query execution is an optimization technique where a driver +pre-emptively starts a second execution of a query against another node, +before the first node has replied.

            +

            There are multiple speculative execution strategies that the driver can use. +Speculative execution can be configured for the whole whole Session during +its creation.

            +

            Available speculative execution strategies:

            + +

            Speculative execution is not enabled by default, and currently only +non-iter session methods use it.

            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/tracing/basic.html b/v0.13.0/tracing/basic.html new file mode 100644 index 0000000000..77a30edee2 --- /dev/null +++ b/v0.13.0/tracing/basic.html @@ -0,0 +1,698 @@ + + + + + + + + + + + + + Tracing a simple/prepared/batch query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Tracing a simple/prepared/batch query

            +

            Simple query, prepared query and batch query +return a QueryResult which contains a tracing_id if tracing was enabled.

            +
            +

            Tracing a simple query

            +
            use scylla::query::Query;
            +use scylla::QueryResult;
            +use scylla::tracing::TracingInfo;
            +use uuid::Uuid;
            +
            +// Create a Query manually and enable tracing
            +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)");
            +query.set_tracing(true);
            +
            +let res: QueryResult = session.query(query, &[]).await?;
            +let tracing_id: Option<Uuid> = res.tracing_id;
            +
            +if let Some(id) = tracing_id {
            +    // Query tracing info from system_traces.sessions and system_traces.events
            +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
            +    println!("tracing_info: {:#?}", tracing_info);
            +}
            +
            +
            +
            +
            +

            Tracing a prepared query

            +
            use scylla::prepared_statement::PreparedStatement;
            +use scylla::QueryResult;
            +use scylla::tracing::TracingInfo;
            +use uuid::Uuid;
            +
            +// Prepare the query
            +let mut prepared: PreparedStatement = session
            +    .prepare("SELECT a FROM ks.tab")
            +    .await?;
            +
            +// Enable tracing for the prepared query
            +prepared.set_tracing(true);
            +
            +let res: QueryResult = session.execute(&prepared, &[]).await?;
            +let tracing_id: Option<Uuid> = res.tracing_id;
            +
            +if let Some(id) = tracing_id {
            +    // Query tracing info from system_traces.sessions and system_traces.events
            +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
            +    println!("tracing_info: {:#?}", tracing_info);
            +}
            +
            +
            +
            +
            +

            Tracing a batch query

            +
            use scylla::batch::Batch;
            +use scylla::QueryResult;
            +use scylla::tracing::TracingInfo;
            +use uuid::Uuid;
            +
            +// Create a batch statement
            +let mut batch: Batch = Default::default();
            +batch.append_statement("INSERT INTO ks.tab (a) VALUES(4)");
            +
            +// Enable tracing
            +batch.set_tracing(true);
            +
            +let res: QueryResult = session.batch(&batch, ((),)).await?;
            +let tracing_id: Option<Uuid> = res.tracing_id;
            +
            +if let Some(id) = tracing_id {
            +    // Query tracing info from system_traces.sessions and system_traces.events
            +    let tracing_info: TracingInfo = session.get_tracing_info(&id).await?;
            +    println!("tracing_info: {:#?}", tracing_info);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/tracing/paged.html b/v0.13.0/tracing/paged.html new file mode 100644 index 0000000000..e1bc7cc483 --- /dev/null +++ b/v0.13.0/tracing/paged.html @@ -0,0 +1,686 @@ + + + + + + + + + + + + + Tracing a paged query | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Tracing a paged query

            +

            A paged query performs multiple simple/prepared queries to query subsequent pages.
            +If tracing is enabled the row iterator will contain a list of tracing ids for all performed queries.

            +
            +

            Tracing Session::query_iter

            +
            use scylla::query::Query;
            +use scylla::transport::iterator::RowIterator;
            +use scylla::tracing::TracingInfo;
            +use futures::StreamExt;
            +use uuid::Uuid;
            +
            +// Create a Query manually and enable tracing
            +let mut query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(4)");
            +query.set_tracing(true);
            +
            +// Create a paged query iterator and fetch pages
            +let mut row_iterator: RowIterator = session.query_iter(query, &[]).await?;
            +while let Some(_row) = row_iterator.next().await {
            +    // Receive rows
            +}
            +
            +// Now there are tracing ids for each performed query
            +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids();
            +
            +for id in tracing_ids {
            +    // Query tracing info from system_traces.sessions and system_traces.events
            +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
            +    println!("tracing_info: {:#?}", tracing_info);
            +}
            +
            +
            +
            +
            +

            Tracing Session::execute_iter

            +
            use scylla::prepared_statement::PreparedStatement;
            +use scylla::transport::iterator::RowIterator;
            +use scylla::tracing::TracingInfo;
            +use futures::StreamExt;
            +use uuid::Uuid;
            +
            +// Prepare the query
            +let mut prepared: PreparedStatement = session
            +    .prepare("SELECT a FROM ks.tab")
            +    .await?;
            +
            +// Enable tracing for the prepared query
            +prepared.set_tracing(true);
            +
            +// Create a paged query iterator and fetch pages
            +let mut row_iterator: RowIterator = session.execute_iter(prepared, &[]).await?;
            +while let Some(_row) = row_iterator.next().await {
            +    // Receive rows
            +}
            +
            +// Now there are tracing ids for each performed query
            +let tracing_ids: &[Uuid] = row_iterator.get_tracing_ids();
            +
            +for id in tracing_ids {
            +    // Query tracing info from system_traces.sessions and system_traces.events
            +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
            +    println!("tracing_info: {:#?}", tracing_info);
            +}
            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/tracing/prepare.html b/v0.13.0/tracing/prepare.html new file mode 100644 index 0000000000..23c0637b96 --- /dev/null +++ b/v0.13.0/tracing/prepare.html @@ -0,0 +1,634 @@ + + + + + + + + + + + + + Tracing Session::prepare | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Tracing Session::prepare

            +

            Session::prepare prepares a query on all connections. If tracing is enabled for the Query to prepare, the resulting PreparedStatement will contain prepare_tracing_ids. prepare_tracing_ids is a list of tracing ids of prepare requests on all connections.

            +
            use scylla::query::Query;
            +use scylla::prepared_statement::PreparedStatement;
            +use scylla::tracing::TracingInfo;
            +use uuid::Uuid;
            +
            +// Prepare the query with tracing enabled
            +let mut to_prepare: Query = Query::new("SELECT a FROM ks.tab");
            +to_prepare.set_tracing(true);
            +
            +let mut prepared: PreparedStatement = session
            +    .prepare(to_prepare)
            +    .await?;
            +
            +// Now there are tracing ids for each prepare request
            +let tracing_ids: &[Uuid] = &prepared.prepare_tracing_ids;
            +
            +for id in tracing_ids {
            +    // Query tracing info from system_traces.sessions and system_traces.events
            +    let tracing_info: TracingInfo = session.get_tracing_info(id).await?;
            +    println!("tracing_info: {:#?}", tracing_info);
            +}
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/tracing/query-history.html b/v0.13.0/tracing/query-history.html new file mode 100644 index 0000000000..9b513ebd24 --- /dev/null +++ b/v0.13.0/tracing/query-history.html @@ -0,0 +1,733 @@ + + + + + + + + + + + + + Query Execution History | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Query Execution History

            +

            The driver allows to collect history of query execution.
            +This history includes all requests sent, decisions to retry and speculative execution fibers started.

            +
            +

            Example code

            +
            use scylla::query::Query;
            +use scylla::history::{HistoryCollector, StructuredHistory};
            +use std::sync::Arc;
            +
            +// Create a query for which we would like to trace the history of its execution
            +let mut query: Query = Query::new("SELECT * FROM ks.t");
            +
            +// Create a history collector and pass it to the query
            +let history_listener = Arc::new(HistoryCollector::new());
            +query.set_history_listener(history_listener.clone());
            +
            +// Run the query, doesn't matter if it failed, the history will still be saved
            +let _ignore_error = session.query(query.clone(), ()).await;
            +
            +// Access the collected history and print it
            +let structured_history: StructuredHistory = history_listener.clone_structured_history();
            +println!("Query history: {}", structured_history);
            +
            +
            +

            To see more check out the example code

            +
            +
            +

            Output

            +

            Sample output for a query that didn’t encounter any difficulties:

            +
            === Query #0 ===
            +| start_time: 2022-08-25 11:21:50.445075147 UTC
            +| Non-speculative attempts:
            +| - Attempt #0 sent to 127.0.0.1:9042
            +|   request send time: 2022-08-25 11:21:50.445151628 UTC
            +|   Success at 2022-08-25 11:21:50.447444362 UTC
            +|
            +| Query successful at 2022-08-25 11:21:50.447447970 UTC
            +=================
            +
            +
            +

            Here’s output for a query that had some trouble - nodes didn’t respond and speculative execution decided to query others in parallel. +Finally the third node provided a response.

            +
            === Query #0 ===
            +| start_time: 2022-08-26 15:08:28.525367409 UTC
            +| Non-speculative attempts:
            +| - Attempt #0 sent to 127.0.0.219:9042
            +|   request send time: 2022-08-26 15:08:28.525409294 UTC
            +|   No result yet
            +|
            +|
            +| > Speculative fiber #0
            +| fiber start time: 2022-08-26 15:08:28.537074167 UTC
            +| - Attempt #0 sent to 127.0.0.217:9042
            +|   request send time: 2022-08-26 15:08:28.537126083 UTC
            +|   No result yet
            +|
            +|
            +| > Speculative fiber #1
            +| fiber start time: 2022-08-26 15:08:28.548050242 UTC
            +| - Attempt #0 sent to 127.0.0.218:9042
            +|   request send time: 2022-08-26 15:08:28.548089083 UTC
            +|   Success at 2022-08-26 15:08:28.590052778 UTC
            +|
            +| Query successful at 2022-08-26 15:08:28.590078119 UTC
            +=================
            +
            +
            +
            +
            +

            How the driver executes queries

            +

            To read the output it’s useful to understand more about how the driver executes queries.

            +
            +

            No speculative execution

            +

            Without speculative execution the driver performs many attempts sequentially until one of them succeeds. +A single attempt consists of sending a request to some node and waiting for the answer. +In case of an error the driver consults the retry policy to decide what to do next. +The decision might be to fail the query, retry on the same node, another node, change query parameters, etc. +Once the decision is made either the query fails or another attempt is started. This continues until the query ends.

            +
            +
            +

            Speculative execution

            +

            When speculative execution is enabled at first the driver doesn’t care about it - it does the attempts sequentially and tries to get an answer. +However once a specified amount of time has passed it will decide to try new attempts in parallel +hoping that another node will be able to answer quicker. +This is done by spawning a speculative fiber. Each spawned fiber performs sequential attempts just like in non-speculative execution. +Many fibers can be spawned if the answer wasn’t acquired in time.

            +
            +
            +

            StructuredHistory

            +

            StructuredHistory +is a history representation that represents the history by listing attempts for each speculative fiber.

            +
            +
            +
            +

            HistoryListener trait, custom history collecting

            +

            History can be collected by any struct implementing the +HistoryListener trait.

            +

            The implementation of HistoryListener provided by this crate is the +HistoryCollector. +HistoryCollector simply collects all events along with their timestamps.

            +

            Information collected by HistoryCollector is just a stream of events, in order to analyze it it’s possible +to convert it to a structured representation. +StructuredHistory +can be created by calling HistoryCollector::clone_structured_history().

            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file diff --git a/v0.13.0/tracing/tracing.html b/v0.13.0/tracing/tracing.html new file mode 100644 index 0000000000..51d14af7df --- /dev/null +++ b/v0.13.0/tracing/tracing.html @@ -0,0 +1,645 @@ + + + + + + + + + + + + + Query tracing | ScyllaDB Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            +
            + Menu +
            +
            +
            +
            +
            + + + + +
            + +
            + +
            +

            Query tracing

            +

            The driver has utilities for monitoring the execution of queries. +There are two separate ways to get information about what happened with a query: Tracing and Query Execution History.

            +
            +

            Tracing

            +

            Tracing is a feature provided by Scylla. When sending a query we can set a flag that signifies that we would like it to be traced. +After completing the query Scylla provides a tracing_id which can be used to fetch information about it - which nodes it was sent to, what operations were performed etc.

            +

            Queries that support tracing:

            + +

            After obtaining the tracing id you can use Session::get_tracing_info() to query tracing information.
            +TracingInfo contains values that are the same in Scylla and Cassandra®, skipping any database-specific ones.
            +If TracingInfo does not contain some needed value it’s possible to query it manually from the tables +system_traces.sessions and system_traces.events

            +
            +
            +

            Query Execution History

            +

            Tracing provides information about how the query execution went on database nodes, but it doesn’t say anything about what was going on inside the driver.
            +This is what query execution history was made for.

            +

            It allows to follow what the driver was thinking - all query attempts, retry decisions, speculative executions. +More information is available in the Query Execution History chapter.

            +
            +
            +
            +
            + + +
            + + + + + + + +
            + +
            + + + + +
            + + + + + + + \ No newline at end of file